commit
a6abe569f9
@ -1,3 +1,4 @@ |
||||
/build |
||||
app-release.apk |
||||
app-google-release.apk |
||||
src/main/res/raw/keystore_tusky_api.bks |
||||
|
@ -1,55 +0,0 @@ |
||||
{ |
||||
"project_info": { |
||||
"project_number": "268851337880", |
||||
"firebase_url": "https://tusky-62772.firebaseio.com", |
||||
"project_id": "tusky-62772", |
||||
"storage_bucket": "tusky-62772.appspot.com" |
||||
}, |
||||
"client": [ |
||||
{ |
||||
"client_info": { |
||||
"mobilesdk_app_id": "1:268851337880:android:fc4111b1d145a00e", |
||||
"android_client_info": { |
||||
"package_name": "com.keylesspalace.tusky" |
||||
} |
||||
}, |
||||
"oauth_client": [ |
||||
{ |
||||
"client_id": "268851337880-eie2ssto2d21bfihn9d1qupcrke8oebf.apps.googleusercontent.com", |
||||
"client_type": 1, |
||||
"android_info": { |
||||
"package_name": "com.keylesspalace.tusky", |
||||
"certificate_hash": "18d196307d6e928e99c2e0bb9818c01c38aff2f9" |
||||
} |
||||
}, |
||||
{ |
||||
"client_id": "268851337880-n19d05m282nirs1fc9kdd5n4of6je4fk.apps.googleusercontent.com", |
||||
"client_type": 3 |
||||
} |
||||
], |
||||
"api_key": [ |
||||
{ |
||||
"current_key": "AIzaSyCbJtSjuk4I3Jy8PdUaO3TaQOXubcOUElo" |
||||
} |
||||
], |
||||
"services": { |
||||
"analytics_service": { |
||||
"status": 1 |
||||
}, |
||||
"appinvite_service": { |
||||
"status": 2, |
||||
"other_platform_oauth_client": [ |
||||
{ |
||||
"client_id": "268851337880-n19d05m282nirs1fc9kdd5n4of6je4fk.apps.googleusercontent.com", |
||||
"client_type": 3 |
||||
} |
||||
] |
||||
}, |
||||
"ads_service": { |
||||
"status": 2 |
||||
} |
||||
} |
||||
} |
||||
], |
||||
"configuration_version": "1" |
||||
} |
@ -1,12 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="com.keylesspalace.tusky"> |
||||
|
||||
<application> |
||||
<service |
||||
android:name=".MessagingService" |
||||
android:enabled="true" |
||||
android:exported="true" /> |
||||
</application> |
||||
|
||||
</manifest> |
@ -1,142 +0,0 @@ |
||||
/* Copyright 2017 Andrew Dawson |
||||
* |
||||
* This file is a part of Tusky. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the |
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even |
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
||||
* Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not, |
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky; |
||||
|
||||
import android.app.IntentService; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.content.SharedPreferences; |
||||
import android.preference.PreferenceManager; |
||||
import android.text.Spanned; |
||||
|
||||
import com.google.gson.Gson; |
||||
import com.google.gson.GsonBuilder; |
||||
|
||||
import com.keylesspalace.tusky.entity.Notification; |
||||
import com.keylesspalace.tusky.json.SpannedTypeAdapter; |
||||
import com.keylesspalace.tusky.json.StringWithEmoji; |
||||
import com.keylesspalace.tusky.json.StringWithEmojiTypeAdapter; |
||||
import com.keylesspalace.tusky.network.MastodonAPI; |
||||
import com.keylesspalace.tusky.util.NotificationMaker; |
||||
import com.keylesspalace.tusky.util.OkHttpUtils; |
||||
|
||||
import java.util.HashSet; |
||||
import java.util.List; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Set; |
||||
|
||||
import okhttp3.Interceptor; |
||||
import okhttp3.OkHttpClient; |
||||
import okhttp3.Request; |
||||
import retrofit2.Call; |
||||
import retrofit2.Callback; |
||||
import retrofit2.Response; |
||||
import retrofit2.Retrofit; |
||||
import retrofit2.converter.gson.GsonConverterFactory; |
||||
|
||||
public class MessagingService extends IntentService { |
||||
public static final int NOTIFY_ID = 6; // This is an arbitrary number.
|
||||
|
||||
private MastodonAPI mastodonAPI; |
||||
|
||||
public MessagingService() { |
||||
super("Tusky Pull Notification Service"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onHandleIntent(Intent intent) { |
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences( |
||||
getApplicationContext()); |
||||
boolean enabled = preferences.getBoolean("notificationsEnabled", true); |
||||
if (!enabled) { |
||||
return; |
||||
} |
||||
|
||||
createMastodonApi(); |
||||
|
||||
mastodonAPI.notifications(null, null, null).enqueue(new Callback<List<Notification>>() { |
||||
@Override |
||||
public void onResponse(Call<List<Notification>> call, |
||||
Response<List<Notification>> response) { |
||||
if (response.isSuccessful()) { |
||||
onNotificationsReceived(response.body()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onFailure(Call<List<Notification>> call, Throwable t) {} |
||||
}); |
||||
} |
||||
|
||||
private void createMastodonApi() { |
||||
SharedPreferences preferences = getSharedPreferences( |
||||
getString(R.string.preferences_file_key), Context.MODE_PRIVATE); |
||||
final String domain = preferences.getString("domain", null); |
||||
final String accessToken = preferences.getString("accessToken", null); |
||||
|
||||
OkHttpClient okHttpClient = OkHttpUtils.getCompatibleClientBuilder() |
||||
.addInterceptor(new Interceptor() { |
||||
@Override |
||||
public okhttp3.Response intercept(Chain chain) throws IOException { |
||||
Request originalRequest = chain.request(); |
||||
|
||||
Request.Builder builder = originalRequest.newBuilder() |
||||
.header("Authorization", String.format("Bearer %s", accessToken)); |
||||
|
||||
Request newRequest = builder.build(); |
||||
|
||||
return chain.proceed(newRequest); |
||||
} |
||||
}) |
||||
.build(); |
||||
|
||||
Gson gson = new GsonBuilder() |
||||
.registerTypeAdapter(Spanned.class, new SpannedTypeAdapter()) |
||||
.registerTypeAdapter(StringWithEmoji.class, new StringWithEmojiTypeAdapter()) |
||||
.create(); |
||||
|
||||
Retrofit retrofit = new Retrofit.Builder() |
||||
.baseUrl("https://" + domain) |
||||
.client(okHttpClient) |
||||
.addConverterFactory(GsonConverterFactory.create(gson)) |
||||
.build(); |
||||
|
||||
mastodonAPI = retrofit.create(MastodonAPI.class); |
||||
} |
||||
|
||||
private void onNotificationsReceived(List<Notification> notificationList) { |
||||
SharedPreferences notificationsPreferences = getSharedPreferences( |
||||
"Notifications", Context.MODE_PRIVATE); |
||||
Set<String> currentIds = notificationsPreferences.getStringSet( |
||||
"current_ids", new HashSet<String>()); |
||||
for (Notification notification : notificationList) { |
||||
String id = notification.id; |
||||
if (!currentIds.contains(id)) { |
||||
currentIds.add(id); |
||||
NotificationMaker.make(this, NOTIFY_ID, notification); |
||||
} |
||||
} |
||||
notificationsPreferences.edit() |
||||
.putStringSet("current_ids", currentIds) |
||||
.apply(); |
||||
} |
||||
|
||||
public static String getInstanceToken() { |
||||
// This is only used for the "google" build flavor, so this version is just a stub method.
|
||||
return null; |
||||
} |
||||
} |
@ -1,18 +0,0 @@ |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="com.keylesspalace.tusky"> |
||||
<application> |
||||
<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" /> |
||||
|
||||
<service android:name=".MyFirebaseInstanceIdService" android:exported="true"> |
||||
<intent-filter> |
||||
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> |
||||
</intent-filter> |
||||
</service> |
||||
|
||||
<service android:name=".MessagingService" android:exported="true"> |
||||
<intent-filter> |
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" /> |
||||
</intent-filter> |
||||
</service> |
||||
</application> |
||||
</manifest> |
@ -1,133 +0,0 @@ |
||||
/* Copyright 2017 Andrew Dawson |
||||
* |
||||
* This file is a part of Tusky. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the |
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even |
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
||||
* Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not, |
||||
* see <http://www.gnu.org/licenses>.
|
||||
* |
||||
* If you modify this Program, or any covered work, by linking or combining it with Firebase Cloud |
||||
* Messaging and Firebase Crash Reporting (or a modified version of those libraries), containing |
||||
* parts covered by the Google APIs Terms of Service, the licensors of this Program grant you |
||||
* additional permission to convey the resulting work. */ |
||||
|
||||
package com.keylesspalace.tusky; |
||||
|
||||
import android.content.Context; |
||||
import android.content.SharedPreferences; |
||||
import android.preference.PreferenceManager; |
||||
import android.text.Spanned; |
||||
|
||||
import com.google.firebase.iid.FirebaseInstanceId; |
||||
import com.google.firebase.messaging.FirebaseMessagingService; |
||||
import com.google.firebase.messaging.RemoteMessage; |
||||
import com.google.gson.Gson; |
||||
import com.google.gson.GsonBuilder; |
||||
|
||||
import com.keylesspalace.tusky.entity.Notification; |
||||
import com.keylesspalace.tusky.json.SpannedTypeAdapter; |
||||
import com.keylesspalace.tusky.json.StringWithEmoji; |
||||
import com.keylesspalace.tusky.json.StringWithEmojiTypeAdapter; |
||||
import com.keylesspalace.tusky.network.MastodonAPI; |
||||
import com.keylesspalace.tusky.util.Log; |
||||
import com.keylesspalace.tusky.util.NotificationMaker; |
||||
import com.keylesspalace.tusky.util.OkHttpUtils; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import okhttp3.Interceptor; |
||||
import okhttp3.OkHttpClient; |
||||
import okhttp3.Request; |
||||
import retrofit2.Call; |
||||
import retrofit2.Callback; |
||||
import retrofit2.Response; |
||||
import retrofit2.Retrofit; |
||||
import retrofit2.converter.gson.GsonConverterFactory; |
||||
|
||||
public class MessagingService extends FirebaseMessagingService { |
||||
private MastodonAPI mastodonAPI; |
||||
private static final String TAG = "MessagingService"; |
||||
public static final int NOTIFY_ID = 666; |
||||
|
||||
@Override |
||||
public void onMessageReceived(RemoteMessage remoteMessage) { |
||||
Log.d(TAG, remoteMessage.getFrom()); |
||||
Log.d(TAG, remoteMessage.toString()); |
||||
|
||||
String notificationId = remoteMessage.getData().get("notification_id"); |
||||
|
||||
if (notificationId == null) { |
||||
Log.e(TAG, "No notification ID in payload!!"); |
||||
return; |
||||
} |
||||
|
||||
Log.d(TAG, notificationId); |
||||
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences( |
||||
getApplicationContext()); |
||||
boolean enabled = preferences.getBoolean("notificationsEnabled", true); |
||||
if (!enabled) { |
||||
return; |
||||
} |
||||
|
||||
createMastodonAPI(); |
||||
|
||||
mastodonAPI.notification(notificationId).enqueue(new Callback<Notification>() { |
||||
@Override |
||||
public void onResponse(Call<Notification> call, Response<Notification> response) { |
||||
if (response.isSuccessful()) { |
||||
NotificationMaker.make(MessagingService.this, NOTIFY_ID, response.body()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onFailure(Call<Notification> call, Throwable t) {} |
||||
}); |
||||
} |
||||
|
||||
private void createMastodonAPI() { |
||||
SharedPreferences preferences = getSharedPreferences(getString(R.string.preferences_file_key), Context.MODE_PRIVATE); |
||||
final String domain = preferences.getString("domain", null); |
||||
final String accessToken = preferences.getString("accessToken", null); |
||||
|
||||
OkHttpClient okHttpClient = OkHttpUtils.getCompatibleClientBuilder() |
||||
.addInterceptor(new Interceptor() { |
||||
@Override |
||||
public okhttp3.Response intercept(Chain chain) throws IOException { |
||||
Request originalRequest = chain.request(); |
||||
|
||||
Request.Builder builder = originalRequest.newBuilder() |
||||
.header("Authorization", String.format("Bearer %s", accessToken)); |
||||
|
||||
Request newRequest = builder.build(); |
||||
|
||||
return chain.proceed(newRequest); |
||||
} |
||||
}) |
||||
.build(); |
||||
|
||||
Gson gson = new GsonBuilder() |
||||
.registerTypeAdapter(Spanned.class, new SpannedTypeAdapter()) |
||||
.registerTypeAdapter(StringWithEmoji.class, new StringWithEmojiTypeAdapter()) |
||||
.create(); |
||||
|
||||
Retrofit retrofit = new Retrofit.Builder() |
||||
.baseUrl("https://" + domain) |
||||
.client(okHttpClient) |
||||
.addConverterFactory(GsonConverterFactory.create(gson)) |
||||
.build(); |
||||
|
||||
mastodonAPI = retrofit.create(MastodonAPI.class); |
||||
} |
||||
|
||||
public static String getInstanceToken() { |
||||
return FirebaseInstanceId.getInstance().getToken(); |
||||
} |
||||
} |
@ -1,86 +0,0 @@ |
||||
/* Copyright 2017 Andrew Dawson |
||||
* |
||||
* This file is a part of Tusky. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the |
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even |
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
||||
* Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not, |
||||
* see <http://www.gnu.org/licenses>.
|
||||
* |
||||
* If you modify this Program, or any covered work, by linking or combining it with Firebase Cloud |
||||
* Messaging and Firebase Crash Reporting (or a modified version of those libraries), containing |
||||
* parts covered by the Google APIs Terms of Service, the licensors of this Program grant you |
||||
* additional permission to convey the resulting work. */ |
||||
|
||||
package com.keylesspalace.tusky; |
||||
|
||||
import android.content.Context; |
||||
import android.content.SharedPreferences; |
||||
|
||||
import com.google.firebase.iid.FirebaseInstanceId; |
||||
import com.google.firebase.iid.FirebaseInstanceIdService; |
||||
import com.keylesspalace.tusky.network.TuskyAPI; |
||||
import com.keylesspalace.tusky.util.Log; |
||||
import com.keylesspalace.tusky.util.OkHttpUtils; |
||||
|
||||
import okhttp3.ResponseBody; |
||||
import retrofit2.Call; |
||||
import retrofit2.Callback; |
||||
import retrofit2.Response; |
||||
import retrofit2.Retrofit; |
||||
|
||||
public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService { |
||||
private static final String TAG = "com.keylesspalace.tusky.MyFirebaseInstanceIdService"; |
||||
|
||||
private TuskyAPI tuskyAPI; |
||||
|
||||
protected void createTuskyAPI() { |
||||
Retrofit retrofit = new Retrofit.Builder() |
||||
.baseUrl(getString(R.string.tusky_api_url)) |
||||
.client(OkHttpUtils.getCompatibleClient()) |
||||
.build(); |
||||
|
||||
tuskyAPI = retrofit.create(TuskyAPI.class); |
||||
} |
||||
|
||||
@Override |
||||
public void onTokenRefresh() { |
||||
createTuskyAPI(); |
||||
|
||||
String refreshedToken = FirebaseInstanceId.getInstance().getToken(); |
||||
SharedPreferences preferences = getSharedPreferences(getString(R.string.preferences_file_key), Context.MODE_PRIVATE); |
||||
String accessToken = preferences.getString("accessToken", null); |
||||
String domain = preferences.getString("domain", null); |
||||
|
||||
if (accessToken != null && domain != null) { |
||||
tuskyAPI.unregister("https://" + domain, accessToken).enqueue(new Callback<ResponseBody>() { |
||||
@Override |
||||
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { |
||||
Log.d(TAG, response.message()); |
||||
} |
||||
|
||||
@Override |
||||
public void onFailure(Call<ResponseBody> call, Throwable t) { |
||||
Log.d(TAG, t.getMessage()); |
||||
} |
||||
}); |
||||
tuskyAPI.register("https://" + domain, accessToken, refreshedToken).enqueue(new Callback<ResponseBody>() { |
||||
@Override |
||||
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { |
||||
Log.d(TAG, response.message()); |
||||
} |
||||
|
||||
@Override |
||||
public void onFailure(Call<ResponseBody> call, Throwable t) { |
||||
Log.d(TAG, t.getMessage()); |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
/* Copyright 2017 Andrew Dawson |
||||
* |
||||
* This file is a part of Tusky. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the |
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even |
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
||||
* Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not, |
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.entity; |
||||
|
||||
public class Session { |
||||
public String instanceUrl; |
||||
public String accessToken; |
||||
public String deviceToken; |
||||
|
||||
public Session(String instanceUrl, String accessToken, String deviceToken) { |
||||
this.instanceUrl = instanceUrl; |
||||
this.accessToken = accessToken; |
||||
this.deviceToken = deviceToken; |
||||
} |
||||
} |
@ -0,0 +1,237 @@ |
||||
package com.keylesspalace.tusky.util; |
||||
|
||||
import android.app.NotificationManager; |
||||
import android.content.Context; |
||||
import android.support.annotation.NonNull; |
||||
import android.text.Spanned; |
||||
|
||||
import com.google.gson.Gson; |
||||
import com.google.gson.GsonBuilder; |
||||
import com.keylesspalace.tusky.R; |
||||
import com.keylesspalace.tusky.entity.Notification; |
||||
import com.keylesspalace.tusky.json.SpannedTypeAdapter; |
||||
import com.keylesspalace.tusky.json.StringWithEmoji; |
||||
import com.keylesspalace.tusky.json.StringWithEmojiTypeAdapter; |
||||
|
||||
import org.eclipse.paho.android.service.MqttAndroidClient; |
||||
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions; |
||||
import org.eclipse.paho.client.mqttv3.IMqttActionListener; |
||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; |
||||
import org.eclipse.paho.client.mqttv3.IMqttToken; |
||||
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended; |
||||
import org.eclipse.paho.client.mqttv3.MqttClient; |
||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions; |
||||
import org.eclipse.paho.client.mqttv3.MqttException; |
||||
import org.eclipse.paho.client.mqttv3.MqttMessage; |
||||
|
||||
import java.io.InputStream; |
||||
import java.util.ArrayDeque; |
||||
import java.util.ArrayList; |
||||
|
||||
import static android.content.Context.NOTIFICATION_SERVICE; |
||||
|
||||
public class PushNotificationClient { |
||||
private static final String TAG = "PushNotificationClient"; |
||||
private static final int NOTIFY_ID = 666; |
||||
|
||||
private static class QueuedAction { |
||||
enum Type { |
||||
SUBSCRIBE, |
||||
UNSUBSCRIBE, |
||||
DISCONNECT, |
||||
} |
||||
|
||||
Type type; |
||||
String topic; |
||||
|
||||
QueuedAction(Type type) { |
||||
this.type = type; |
||||
} |
||||
|
||||
QueuedAction(Type type, String topic) { |
||||
this.type = type; |
||||
this.topic = topic; |
||||
} |
||||
} |
||||
|
||||
private MqttAndroidClient mqttAndroidClient; |
||||
private ArrayDeque<QueuedAction> queuedActions; |
||||
private ArrayList<String> subscribedTopics; |
||||
|
||||
public PushNotificationClient(final @NonNull Context applicationContext, |
||||
@NonNull String serverUri) { |
||||
queuedActions = new ArrayDeque<>(); |
||||
subscribedTopics = new ArrayList<>(); |
||||
|
||||
// Create the MQTT client.
|
||||
String clientId = MqttClient.generateClientId(); |
||||
mqttAndroidClient = new MqttAndroidClient(applicationContext, serverUri, clientId); |
||||
mqttAndroidClient.setCallback(new MqttCallbackExtended() { |
||||
@Override |
||||
public void connectComplete(boolean reconnect, String serverURI) { |
||||
if (reconnect) { |
||||
flushQueuedActions(); |
||||
for (String topic : subscribedTopics) { |
||||
subscribeToTopic(topic); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void connectionLost(Throwable cause) { |
||||
onConnectionLost(); |
||||
} |
||||
|
||||
@Override |
||||
public void messageArrived(String topic, MqttMessage message) throws Exception { |
||||
onMessageReceived(applicationContext, new String(message.getPayload())); |
||||
} |
||||
|
||||
@Override |
||||
public void deliveryComplete(IMqttDeliveryToken token) { |
||||
// This client is read-only, so this is unused.
|
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void flushQueuedActions() { |
||||
while (!queuedActions.isEmpty()) { |
||||
QueuedAction action = queuedActions.pop(); |
||||
switch (action.type) { |
||||
case SUBSCRIBE: subscribeToTopic(action.topic); break; |
||||
case UNSUBSCRIBE: unsubscribeToTopic(action.topic); break; |
||||
case DISCONNECT: disconnect(); break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** Connect to the MQTT broker. */ |
||||
public void connect(Context context) { |
||||
MqttConnectOptions options = new MqttConnectOptions(); |
||||
options.setAutomaticReconnect(true); |
||||
options.setCleanSession(false); |
||||
try { |
||||
String password = context.getString(R.string.tusky_api_keystore_password); |
||||
InputStream keystore = context.getResources().openRawResource(R.raw.keystore_tusky_api); |
||||
try { |
||||
options.setSocketFactory(mqttAndroidClient.getSSLSocketFactory(keystore, password)); |
||||
} finally { |
||||
IOUtils.closeQuietly(keystore); |
||||
} |
||||
mqttAndroidClient.connect(options).setActionCallback(new IMqttActionListener() { |
||||
@Override |
||||
public void onSuccess(IMqttToken asyncActionToken) { |
||||
DisconnectedBufferOptions bufferOptions = new DisconnectedBufferOptions(); |
||||
bufferOptions.setBufferEnabled(true); |
||||
bufferOptions.setBufferSize(100); |
||||
bufferOptions.setPersistBuffer(false); |
||||
bufferOptions.setDeleteOldestMessages(false); |
||||
mqttAndroidClient.setBufferOpts(bufferOptions); |
||||
onConnectionSuccess(); |
||||
flushQueuedActions(); |
||||
} |
||||
|
||||
@Override |
||||
public void onFailure(IMqttToken asyncActionToken, Throwable exception) { |
||||
Log.e(TAG, "An exception occurred while connecting. " + exception.getMessage() |
||||
+ " " + exception.getCause()); |
||||
onConnectionFailure(); |
||||
} |
||||
}); |
||||
} catch (MqttException e) { |
||||
Log.e(TAG, "An exception occurred while connecpting. " + e.getMessage()); |
||||
onConnectionFailure(); |
||||
} |
||||
} |
||||
|
||||
private void onConnectionSuccess() { |
||||
Log.v(TAG, "The connection succeeded."); |
||||
} |
||||
|
||||
private void onConnectionFailure() { |
||||
Log.v(TAG, "The connection failed."); |
||||
} |
||||
|
||||
private void onConnectionLost() { |
||||
Log.v(TAG, "The connection was lost."); |
||||
} |
||||
|
||||
/** Disconnect from the MQTT broker. */ |
||||
public void disconnect() { |
||||
if (!mqttAndroidClient.isConnected()) { |
||||
queuedActions.add(new QueuedAction(QueuedAction.Type.DISCONNECT)); |
||||
return; |
||||
} |
||||
try { |
||||
mqttAndroidClient.disconnect(); |
||||
} catch (MqttException ex) { |
||||
Log.e(TAG, "An exception occurred while disconnecting."); |
||||
onDisconnectFailed(); |
||||
} |
||||
} |
||||
|
||||
private void onDisconnectFailed() { |
||||
Log.v(TAG, "Failed while disconnecting from the broker."); |
||||
} |
||||
|
||||
/** Subscribe to the push notification topic. */ |
||||
public void subscribeToTopic(final String topic) { |
||||
if (!mqttAndroidClient.isConnected()) { |
||||
queuedActions.add(new QueuedAction(QueuedAction.Type.SUBSCRIBE, topic)); |
||||
return; |
||||
} |
||||
try { |
||||
mqttAndroidClient.subscribe(topic, 0, null, new IMqttActionListener() { |
||||
@Override |
||||
public void onSuccess(IMqttToken asyncActionToken) { |
||||
subscribedTopics.add(topic); |
||||
onConnectionSuccess(); |
||||
} |
||||
|
||||
@Override |
||||
public void onFailure(IMqttToken asyncActionToken, Throwable exception) { |
||||
Log.e(TAG, "An exception occurred while subscribing." + exception.getMessage()); |
||||
onConnectionFailure(); |
||||
} |
||||
}); |
||||
} catch (MqttException e) { |
||||
Log.e(TAG, "An exception occurred while subscribing." + e.getMessage()); |
||||
onConnectionFailure(); |
||||
} |
||||
} |
||||
|
||||
/** Unsubscribe from the push notification topic. */ |
||||
public void unsubscribeToTopic(String topic) { |
||||
if (!mqttAndroidClient.isConnected()) { |
||||
queuedActions.add(new QueuedAction(QueuedAction.Type.UNSUBSCRIBE, topic)); |
||||
return; |
||||
} |
||||
try { |
||||
mqttAndroidClient.unsubscribe(topic); |
||||
subscribedTopics.remove(topic); |
||||
} catch (MqttException e) { |
||||
Log.e(TAG, "An exception occurred while unsubscribing." + e.getMessage()); |
||||
onConnectionFailure(); |
||||
} |
||||
} |
||||
|
||||
private void onMessageReceived(final Context context, String message) { |
||||
Log.v(TAG, "Notification received: " + message); |
||||
|
||||
Gson gson = new GsonBuilder() |
||||
.registerTypeAdapter(Spanned.class, new SpannedTypeAdapter()) |
||||
.registerTypeAdapter(StringWithEmoji.class, new StringWithEmojiTypeAdapter()) |
||||
.create(); |
||||
Notification notification = gson.fromJson(message, Notification.class); |
||||
|
||||
NotificationMaker.make(context, NOTIFY_ID, notification); |
||||
} |
||||
|
||||
public void clearNotifications(Context context) { |
||||
((NotificationManager) (context.getSystemService(NOTIFICATION_SERVICE))).cancel(NOTIFY_ID); |
||||
} |
||||
|
||||
public String getDeviceToken() { |
||||
return mqttAndroidClient.getClientId(); |
||||
} |
||||
} |
Loading…
Reference in new issue