mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-24 02:25:19 +00:00
Add support for notification reminders.
// FREEBIE Closes #1623 Fixes #323
This commit is contained in:
parent
6e7566f781
commit
df12174458
@ -215,7 +215,6 @@
|
|||||||
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
|
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
|
||||||
<service android:enabled="true" android:name=".service.KeyCachingService"/>
|
<service android:enabled="true" android:name=".service.KeyCachingService"/>
|
||||||
<service android:enabled="true" android:name=".service.RegistrationService"/>
|
<service android:enabled="true" android:name=".service.RegistrationService"/>
|
||||||
<service android:enabled="true" android:name=".service.DirectoryRefreshService"/>
|
|
||||||
|
|
||||||
<service android:name=".service.QuickResponseService"
|
<service android:name=".service.QuickResponseService"
|
||||||
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
|
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
|
||||||
@ -305,6 +304,17 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name=".notifications.MessageNotifier$ReminderReceiver">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="org.thoughtcrime.securesms.MessageNotifier.REMINDER_ACTION"/>
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name=".notifications.MessageNotifier$DeleteReceiver">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="org.thoughtcrime.securesms.MessageNotifier.DELETE_REMINDER_ACTION"/>
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
<uses-library android:name="android.test.runner" />
|
<uses-library android:name="android.test.runner" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -184,4 +184,22 @@
|
|||||||
<item>@drawable/ic_send_sms_secure</item>
|
<item>@drawable/ic_send_sms_secure</item>
|
||||||
<item>@drawable/ic_send_push</item>
|
<item>@drawable/ic_send_push</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_repeat_alerts_entries">
|
||||||
|
<item>Never</item>
|
||||||
|
<item>One time</item>
|
||||||
|
<item>Two times</item>
|
||||||
|
<item>Three times</item>
|
||||||
|
<item>Five times</item>
|
||||||
|
<item>Ten times</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_repeat_alerts_values" translatable="false">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
<item>3</item>
|
||||||
|
<item>5</item>
|
||||||
|
<item>10</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -6,6 +6,19 @@
|
|||||||
android:summary="@string/preferences__display_message_notifications_in_status_bar"
|
android:summary="@string/preferences__display_message_notifications_in_status_bar"
|
||||||
android:defaultValue="true" />
|
android:defaultValue="true" />
|
||||||
|
|
||||||
|
<RingtonePreference android:dependency="pref_key_enable_notifications"
|
||||||
|
android:key="pref_key_ringtone"
|
||||||
|
android:title="@string/preferences__sound"
|
||||||
|
android:summary="@string/preferences__change_notification_sound"
|
||||||
|
android:ringtoneType="notification"
|
||||||
|
android:defaultValue="content://settings/system/notification_sound" />
|
||||||
|
|
||||||
|
<CheckBoxPreference android:dependency="pref_key_enable_notifications"
|
||||||
|
android:key="pref_key_vibrate"
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:title="@string/preferences__vibrate"
|
||||||
|
android:summary="@string/preferences__also_vibrate_when_notified" />
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="pref_led_color"
|
android:key="pref_led_color"
|
||||||
android:defaultValue="green"
|
android:defaultValue="green"
|
||||||
@ -22,12 +35,6 @@
|
|||||||
android:entries="@array/pref_led_blink_pattern_entries"
|
android:entries="@array/pref_led_blink_pattern_entries"
|
||||||
android:entryValues="@array/pref_led_blink_pattern_values" />
|
android:entryValues="@array/pref_led_blink_pattern_values" />
|
||||||
|
|
||||||
<RingtonePreference android:dependency="pref_key_enable_notifications"
|
|
||||||
android:key="pref_key_ringtone"
|
|
||||||
android:title="@string/preferences__sound"
|
|
||||||
android:summary="@string/preferences__change_notification_sound"
|
|
||||||
android:ringtoneType="notification"
|
|
||||||
android:defaultValue="content://settings/system/notification_sound" />
|
|
||||||
|
|
||||||
<CheckBoxPreference android:key="pref_key_inthread_notifications"
|
<CheckBoxPreference android:key="pref_key_inthread_notifications"
|
||||||
android:title="@string/preferences__inthread_notifications"
|
android:title="@string/preferences__inthread_notifications"
|
||||||
@ -35,9 +42,11 @@
|
|||||||
android:dependency="pref_key_enable_notifications"
|
android:dependency="pref_key_enable_notifications"
|
||||||
android:defaultValue="true" />
|
android:defaultValue="true" />
|
||||||
|
|
||||||
<CheckBoxPreference android:dependency="pref_key_enable_notifications"
|
<ListPreference
|
||||||
android:key="pref_key_vibrate"
|
android:key="pref_repeat_alerts"
|
||||||
android:defaultValue="true"
|
android:defaultValue="0"
|
||||||
android:title="@string/preferences__vibrate"
|
android:title="Repeat alerts"
|
||||||
android:summary="@string/preferences__also_vibrate_when_notified" />
|
android:dependency="pref_key_enable_notifications"
|
||||||
|
android:entries="@array/pref_repeat_alerts_entries"
|
||||||
|
android:entryValues="@array/pref_repeat_alerts_values" />
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
@ -16,9 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.thoughtcrime.securesms.notifications;
|
package org.thoughtcrime.securesms.notifications;
|
||||||
|
|
||||||
|
import android.app.AlarmManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@ -40,23 +42,24 @@ import android.util.Log;
|
|||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.RoutingActivity;
|
import org.thoughtcrime.securesms.RoutingActivity;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.PushDatabase;
|
import org.thoughtcrime.securesms.database.PushDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
|
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.whispersystems.textsecure.api.messages.TextSecureEnvelope;
|
import org.whispersystems.textsecure.api.messages.TextSecureEnvelope;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import me.leolin.shortcutbadger.ShortcutBadgeException;
|
|
||||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
import me.leolin.shortcutbadger.ShortcutBadger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,13 +105,12 @@ public class MessageNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void updateNotification(Context context, MasterSecret masterSecret) {
|
public static void updateNotification(Context context, MasterSecret masterSecret) {
|
||||||
if (!TextSecurePreferences.isNotificationsEnabled(context)) {
|
if (!TextSecurePreferences.isNotificationsEnabled(context)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNotification(context, masterSecret, false);
|
updateNotification(context, masterSecret, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateNotification(Context context, MasterSecret masterSecret, long threadId) {
|
public static void updateNotification(Context context, MasterSecret masterSecret, long threadId) {
|
||||||
@ -120,11 +122,11 @@ public class MessageNotifier {
|
|||||||
DatabaseFactory.getThreadDatabase(context).setRead(threadId);
|
DatabaseFactory.getThreadDatabase(context).setRead(threadId);
|
||||||
sendInThreadNotification(context);
|
sendInThreadNotification(context);
|
||||||
} else {
|
} else {
|
||||||
updateNotification(context, masterSecret, true);
|
updateNotification(context, masterSecret, true, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateNotification(Context context, MasterSecret masterSecret, boolean signal) {
|
private static void updateNotification(Context context, MasterSecret masterSecret, boolean signal, int reminderCount) {
|
||||||
Cursor telcoCursor = null;
|
Cursor telcoCursor = null;
|
||||||
Cursor pushCursor = null;
|
Cursor pushCursor = null;
|
||||||
|
|
||||||
@ -138,6 +140,7 @@ public class MessageNotifier {
|
|||||||
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
||||||
.cancel(NOTIFICATION_ID);
|
.cancel(NOTIFICATION_ID);
|
||||||
updateBadge(context, 0);
|
updateBadge(context, 0);
|
||||||
|
clearReminder(context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +155,7 @@ public class MessageNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateBadge(context, notificationState.getMessageCount());
|
updateBadge(context, notificationState.getMessageCount());
|
||||||
|
scheduleReminder(context, masterSecret, reminderCount);
|
||||||
} finally {
|
} finally {
|
||||||
if (telcoCursor != null) telcoCursor.close();
|
if (telcoCursor != null) telcoCursor.close();
|
||||||
if (pushCursor != null) pushCursor.close();
|
if (pushCursor != null) pushCursor.close();
|
||||||
@ -180,6 +184,7 @@ public class MessageNotifier {
|
|||||||
builder.setContentIntent(notifications.get(0).getPendingIntent(context));
|
builder.setContentIntent(notifications.get(0).getPendingIntent(context));
|
||||||
builder.setContentInfo(String.valueOf(notificationState.getMessageCount()));
|
builder.setContentInfo(String.valueOf(notificationState.getMessageCount()));
|
||||||
builder.setNumber(notificationState.getMessageCount());
|
builder.setNumber(notificationState.getMessageCount());
|
||||||
|
builder.setDeleteIntent(PendingIntent.getBroadcast(context, 0, new Intent(DeleteReceiver.DELETE_REMINDER_ACTION), 0));
|
||||||
|
|
||||||
if (masterSecret != null) {
|
if (masterSecret != null) {
|
||||||
builder.addAction(R.drawable.check, context.getString(R.string.MessageNotifier_mark_as_read),
|
builder.addAction(R.drawable.check, context.getString(R.string.MessageNotifier_mark_as_read),
|
||||||
@ -227,6 +232,8 @@ public class MessageNotifier {
|
|||||||
builder.setContentInfo(String.valueOf(notificationState.getMessageCount()));
|
builder.setContentInfo(String.valueOf(notificationState.getMessageCount()));
|
||||||
builder.setNumber(notificationState.getMessageCount());
|
builder.setNumber(notificationState.getMessageCount());
|
||||||
|
|
||||||
|
builder.setDeleteIntent(PendingIntent.getBroadcast(context, 0, new Intent(DeleteReceiver.DELETE_REMINDER_ACTION), 0));
|
||||||
|
|
||||||
if (masterSecret != null) {
|
if (masterSecret != null) {
|
||||||
builder.addAction(R.drawable.check, context.getString(R.string.MessageNotifier_mark_all_as_read),
|
builder.addAction(R.drawable.check, context.getString(R.string.MessageNotifier_mark_all_as_read),
|
||||||
notificationState.getMarkAsReadIntent(context, masterSecret));
|
notificationState.getMarkAsReadIntent(context, masterSecret));
|
||||||
@ -400,4 +407,48 @@ public class MessageNotifier {
|
|||||||
Log.w("MessageNotifier", t);
|
Log.w("MessageNotifier", t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void scheduleReminder(Context context, MasterSecret masterSecret, int count) {
|
||||||
|
if (count >= TextSecurePreferences.getRepeatAlertsCount(context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
Intent alarmIntent = new Intent(ReminderReceiver.REMINDER_ACTION);
|
||||||
|
alarmIntent.putExtra("reminder_count", count);
|
||||||
|
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
long timeout = TimeUnit.SECONDS.toMillis(10);
|
||||||
|
|
||||||
|
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, pendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void clearReminder(Context context) {
|
||||||
|
Intent alarmIntent = new Intent(ReminderReceiver.REMINDER_ACTION);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
alarmManager.cancel(pendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ReminderReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
public static final String REMINDER_ACTION = "org.thoughtcrime.securesms.MessageNotifier.REMINDER_ACTION";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
MasterSecret masterSecret = KeyCachingService.getMasterSecret(context);
|
||||||
|
int reminderCount = intent.getIntExtra("reminder_count", 0);
|
||||||
|
MessageNotifier.updateNotification(context, masterSecret, true, reminderCount + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DeleteReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
public static final String DELETE_REMINDER_ACTION = "org.thoughtcrime.securesms.MessageNotifier.DELETE_REMINDER_ACTION";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
clearReminder(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,12 @@ public class NotificationsPreferenceFragment extends PreferenceFragment {
|
|||||||
.setOnPreferenceChangeListener(new ListSummaryListener());
|
.setOnPreferenceChangeListener(new ListSummaryListener());
|
||||||
this.findPreference(TextSecurePreferences.RINGTONE_PREF)
|
this.findPreference(TextSecurePreferences.RINGTONE_PREF)
|
||||||
.setOnPreferenceChangeListener(new RingtoneSummaryListener());
|
.setOnPreferenceChangeListener(new RingtoneSummaryListener());
|
||||||
|
this.findPreference(TextSecurePreferences.REPEAT_ALERTS_PREF)
|
||||||
|
.setOnPreferenceChangeListener(new ListSummaryListener());
|
||||||
|
|
||||||
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_COLOR_PREF));
|
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_COLOR_PREF));
|
||||||
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_BLINK_PREF));
|
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_BLINK_PREF));
|
||||||
|
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.REPEAT_ALERTS_PREF));
|
||||||
initializeRingtoneSummary((RingtonePreference) findPreference(TextSecurePreferences.RINGTONE_PREF));
|
initializeRingtoneSummary((RingtonePreference) findPreference(TextSecurePreferences.RINGTONE_PREF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public class TextSecurePreferences {
|
public class TextSecurePreferences {
|
||||||
|
|
||||||
|
private static final String TAG = TextSecurePreferences.class.getSimpleName();
|
||||||
|
|
||||||
public static final String IDENTITY_PREF = "pref_choose_identity";
|
public static final String IDENTITY_PREF = "pref_choose_identity";
|
||||||
public static final String CHANGE_PASSPHRASE_PREF = "pref_change_passphrase";
|
public static final String CHANGE_PASSPHRASE_PREF = "pref_change_passphrase";
|
||||||
public static final String DISABLE_PASSPHRASE_PREF = "pref_disable_passphrase";
|
public static final String DISABLE_PASSPHRASE_PREF = "pref_disable_passphrase";
|
||||||
@ -56,6 +58,25 @@ public class TextSecurePreferences {
|
|||||||
private static final String FALLBACK_MMS_ENABLED_PREF = "pref_mms_fallback_enabled";
|
private static final String FALLBACK_MMS_ENABLED_PREF = "pref_mms_fallback_enabled";
|
||||||
private static final String SIGNED_PREKEY_REGISTERED_PREF = "pref_signed_prekey_registered";
|
private static final String SIGNED_PREKEY_REGISTERED_PREF = "pref_signed_prekey_registered";
|
||||||
|
|
||||||
|
private static final String GCM_REGISTRATION_ID_PREF = "pref_gcm_registration_id";
|
||||||
|
private static final String GCM_REGISTRATION_ID_VERSION_PREF = "pref_gcm_registration_id_version";
|
||||||
|
|
||||||
|
private static final String PUSH_REGISTRATION_REMINDER_PREF = "pref_push_registration_reminder";
|
||||||
|
public static final String REPEAT_ALERTS_PREF = "pref_repeat_alerts";
|
||||||
|
|
||||||
|
public static int getRepeatAlertsCount(Context context) {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(getStringPreference(context, REPEAT_ALERTS_PREF, "0"));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setRepeatAlertsCount(Context context, int count) {
|
||||||
|
setStringPreference(context, REPEAT_ALERTS_PREF, String.valueOf(count));
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isSignedPreKeyRegistered(Context context) {
|
public static boolean isSignedPreKeyRegistered(Context context) {
|
||||||
return getBooleanPreference(context, SIGNED_PREKEY_REGISTERED_PREF, false);
|
return getBooleanPreference(context, SIGNED_PREKEY_REGISTERED_PREF, false);
|
||||||
}
|
}
|
||||||
@ -64,11 +85,6 @@ public class TextSecurePreferences {
|
|||||||
setBooleanPreference(context, SIGNED_PREKEY_REGISTERED_PREF, value);
|
setBooleanPreference(context, SIGNED_PREKEY_REGISTERED_PREF, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String GCM_REGISTRATION_ID_PREF = "pref_gcm_registration_id";
|
|
||||||
private static final String GCM_REGISTRATION_ID_VERSION_PREF = "pref_gcm_registration_id_version";
|
|
||||||
|
|
||||||
private static final String PUSH_REGISTRATION_REMINDER_PREF = "pref_push_registration_reminder";
|
|
||||||
|
|
||||||
public static void setGcmRegistrationId(Context context, String registrationId) {
|
public static void setGcmRegistrationId(Context context, String registrationId) {
|
||||||
setStringPreference(context, GCM_REGISTRATION_ID_PREF, registrationId);
|
setStringPreference(context, GCM_REGISTRATION_ID_PREF, registrationId);
|
||||||
setIntegerPrefrence(context, GCM_REGISTRATION_ID_VERSION_PREF, Util.getCurrentApkReleaseVersion(context));
|
setIntegerPrefrence(context, GCM_REGISTRATION_ID_VERSION_PREF, Util.getCurrentApkReleaseVersion(context));
|
||||||
|
Loading…
Reference in New Issue
Block a user