mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 21:38:33 +00:00
Improve message download reliability.
This commit is contained in:
parent
b5aa46bb67
commit
fb4c9d3bf1
@ -683,6 +683,12 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".gcm.FcmJobService"
|
||||||
|
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||||
|
android:enabled="@bool/enable_job_service"
|
||||||
|
tools:targetApi="26" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".jobmanager.JobSchedulerScheduler$SystemService"
|
android:name=".jobmanager.JobSchedulerScheduler$SystemService"
|
||||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||||
|
@ -784,8 +784,8 @@
|
|||||||
<string name="MessageNotifier_reply">Reply</string>
|
<string name="MessageNotifier_reply">Reply</string>
|
||||||
<string name="MessageNotifier_signal_message">Signal Message</string>
|
<string name="MessageNotifier_signal_message">Signal Message</string>
|
||||||
<string name="MessageNotifier_unsecured_sms">Unsecured SMS</string>
|
<string name="MessageNotifier_unsecured_sms">Unsecured SMS</string>
|
||||||
<string name="MessageNotifier_pending_signal_messages">Pending Signal messages</string>
|
<string name="MessageNotifier_you_may_have_new_messages">You may have new messages</string>
|
||||||
<string name="MessageNotifier_you_have_pending_signal_messages">You have pending Signal messages, tap to open and retrieve</string>
|
<string name="MessageNotifier_open_signal_to_check_for_recent_notifications">Open Signal to check for recent notifications.</string>
|
||||||
<string name="MessageNotifier_contact_message">%1$s %2$s</string>
|
<string name="MessageNotifier_contact_message">%1$s %2$s</string>
|
||||||
<string name="MessageNotifier_unknown_contact_message">Contact</string>
|
<string name="MessageNotifier_unknown_contact_message">Contact</string>
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|||||||
import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule;
|
import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule;
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule;
|
import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule;
|
||||||
|
import org.thoughtcrime.securesms.gcm.FcmJobService;
|
||||||
import org.thoughtcrime.securesms.jobmanager.DependencyInjector;
|
import org.thoughtcrime.securesms.jobmanager.DependencyInjector;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
|
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
|
||||||
@ -135,6 +136,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
|||||||
Log.i(TAG, "App is now visible.");
|
Log.i(TAG, "App is now visible.");
|
||||||
executePendingContactSync();
|
executePendingContactSync();
|
||||||
KeyCachingService.onAppForegrounded(this);
|
KeyCachingService.onAppForegrounded(this);
|
||||||
|
MessageNotifier.cancelMessagesPending(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -334,7 +336,11 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
|||||||
private void initializePendingMessages() {
|
private void initializePendingMessages() {
|
||||||
if (TextSecurePreferences.getNeedsMessagePull(this)) {
|
if (TextSecurePreferences.getNeedsMessagePull(this)) {
|
||||||
Log.i(TAG, "Scheduling a message fetch.");
|
Log.i(TAG, "Scheduling a message fetch.");
|
||||||
ApplicationContext.getInstance(this).getJobManager().add(new PushNotificationReceiveJob(this));
|
if (Build.VERSION.SDK_INT >= 26) {
|
||||||
|
FcmJobService.schedule(this);
|
||||||
|
} else {
|
||||||
|
ApplicationContext.getInstance(this).getJobManager().add(new PushNotificationReceiveJob(this));
|
||||||
|
}
|
||||||
TextSecurePreferences.setNeedsMessagePull(this, false);
|
TextSecurePreferences.setNeedsMessagePull(this, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.CreateProfileActivity;
|
|||||||
import org.thoughtcrime.securesms.DeviceListFragment;
|
import org.thoughtcrime.securesms.DeviceListFragment;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
||||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||||
|
import org.thoughtcrime.securesms.gcm.FcmJobService;
|
||||||
import org.thoughtcrime.securesms.gcm.FcmService;
|
import org.thoughtcrime.securesms.gcm.FcmService;
|
||||||
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
|
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
|
||||||
import org.thoughtcrime.securesms.jobs.AttachmentUploadJob;
|
import org.thoughtcrime.securesms.jobs.AttachmentUploadJob;
|
||||||
@ -108,7 +109,8 @@ import dagger.Provides;
|
|||||||
StickerPackDownloadJob.class,
|
StickerPackDownloadJob.class,
|
||||||
MultiDeviceStickerPackOperationJob.class,
|
MultiDeviceStickerPackOperationJob.class,
|
||||||
MultiDeviceStickerPackSyncJob.class,
|
MultiDeviceStickerPackSyncJob.class,
|
||||||
LinkPreviewRepository.class})
|
LinkPreviewRepository.class,
|
||||||
|
FcmJobService.class})
|
||||||
public class SignalCommunicationModule {
|
public class SignalCommunicationModule {
|
||||||
|
|
||||||
private static final String TAG = SignalCommunicationModule.class.getSimpleName();
|
private static final String TAG = SignalCommunicationModule.class.getSimpleName();
|
||||||
|
77
src/org/thoughtcrime/securesms/gcm/FcmJobService.java
Normal file
77
src/org/thoughtcrime/securesms/gcm/FcmJobService.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package org.thoughtcrime.securesms.gcm;
|
||||||
|
|
||||||
|
import android.app.job.JobInfo;
|
||||||
|
import android.app.job.JobParameters;
|
||||||
|
import android.app.job.JobService;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
|
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
|
||||||
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
|
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||||
|
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||||
|
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pulls down messages. Used when we fail to pull down messages in {@link FcmService}.
|
||||||
|
*/
|
||||||
|
@RequiresApi(26)
|
||||||
|
public class FcmJobService extends JobService implements InjectableType {
|
||||||
|
|
||||||
|
private static final String TAG = FcmJobService.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final int ID = 1337;
|
||||||
|
|
||||||
|
@Inject SignalServiceMessageReceiver messageReceiver;
|
||||||
|
|
||||||
|
@RequiresApi(26)
|
||||||
|
public static void schedule(@NonNull Context context) {
|
||||||
|
JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(ID, new ComponentName(context, FcmJobService.class))
|
||||||
|
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
|
||||||
|
.setBackoffCriteria(0, JobInfo.BACKOFF_POLICY_LINEAR)
|
||||||
|
.setPersisted(true);
|
||||||
|
|
||||||
|
ServiceUtil.getJobScheduler(context).schedule(jobInfoBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onStartJob(JobParameters params) {
|
||||||
|
Log.d(TAG, "onStartJob()");
|
||||||
|
ApplicationContext.getInstance(getApplicationContext()).injectDependencies(this);
|
||||||
|
|
||||||
|
if (ApplicationContext.getInstance(getApplicationContext()).isAppVisible()) {
|
||||||
|
Log.i(TAG, "App is foregrounded. No need to run.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalExecutors.UNBOUNDED.execute(() -> {
|
||||||
|
try {
|
||||||
|
new PushNotificationReceiveJob(getApplicationContext()).pullAndProcessMessages(messageReceiver, TAG, System.currentTimeMillis());
|
||||||
|
jobFinished(params, false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.w(TAG, "Failed to pull. Notifying and scheduling a retry.", e);
|
||||||
|
MessageNotifier.notifyMessagesPending(getApplicationContext());
|
||||||
|
jobFinished(params, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onStopJob(JobParameters params) {
|
||||||
|
Log.d(TAG, "onStopJob()");
|
||||||
|
return TextSecurePreferences.getNeedsMessagePull(getApplicationContext());
|
||||||
|
}
|
||||||
|
}
|
@ -1,33 +1,26 @@
|
|||||||
package org.thoughtcrime.securesms.gcm;
|
package org.thoughtcrime.securesms.gcm;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||||
import com.google.firebase.messaging.RemoteMessage;
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.R;
|
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||||
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
|
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
|
||||||
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
|
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
|
||||||
import org.thoughtcrime.securesms.service.GenericForegroundService;
|
|
||||||
import org.thoughtcrime.securesms.util.PowerManagerCompat;
|
import org.thoughtcrime.securesms.util.PowerManagerCompat;
|
||||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.WakeLockUtil;
|
import org.thoughtcrime.securesms.util.WakeLockUtil;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
||||||
import org.whispersystems.signalservice.internal.util.Util;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -35,8 +28,8 @@ public class FcmService extends FirebaseMessagingService implements InjectableTy
|
|||||||
|
|
||||||
private static final String TAG = FcmService.class.getSimpleName();
|
private static final String TAG = FcmService.class.getSimpleName();
|
||||||
|
|
||||||
private static final Executor MESSAGE_EXECUTOR = SignalExecutors.newCachedSingleThreadExecutor("FcmMessageProcessing");
|
private static final String WAKE_LOCK_TAG = "FcmMessageProcessing";
|
||||||
private static final String WAKE_LOCK_TAG = "FcmMessageProcessing";
|
private static final long SOCKET_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
|
||||||
|
|
||||||
@Inject SignalServiceMessageReceiver messageReceiver;
|
@Inject SignalServiceMessageReceiver messageReceiver;
|
||||||
|
|
||||||
@ -79,69 +72,27 @@ public class FcmService extends FirebaseMessagingService implements InjectableTy
|
|||||||
boolean doze = PowerManagerCompat.isDeviceIdleMode(powerManager);
|
boolean doze = PowerManagerCompat.isDeviceIdleMode(powerManager);
|
||||||
boolean network = new NetworkConstraint.Factory(ApplicationContext.getInstance(context)).create().isMet();
|
boolean network = new NetworkConstraint.Factory(ApplicationContext.getInstance(context)).create().isMet();
|
||||||
|
|
||||||
final Object foregroundLock = new Object();
|
|
||||||
final AtomicBoolean foregroundRunning = new AtomicBoolean(false);
|
|
||||||
final AtomicBoolean taskCompleted = new AtomicBoolean(false);
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
if (doze || !network) {
|
if (doze || !network) {
|
||||||
Log.i(TAG, "Starting a foreground task because we may be operating in a constrained environment. Doze: " + doze + " Network: " + network);
|
Log.w(TAG, "We may be operating in a constrained environment. Doze: " + doze + " Network: " + network);
|
||||||
showForegroundNotification(context);
|
|
||||||
foregroundRunning.set(true);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
MESSAGE_EXECUTOR.execute(() -> {
|
|
||||||
try {
|
|
||||||
new PushNotificationReceiveJob(context).pullAndProcessMessages(messageReceiver, TAG, startTime);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.i(TAG, "Failed to retrieve the envelope. Scheduling on JobManager.", e);
|
|
||||||
ApplicationContext.getInstance(context)
|
|
||||||
.getJobManager()
|
|
||||||
.add(new PushNotificationReceiveJob(context));
|
|
||||||
} finally {
|
|
||||||
synchronized (foregroundLock) {
|
|
||||||
if (foregroundRunning.getAndSet(false)) {
|
|
||||||
GenericForegroundService.stopForegroundTask(context);
|
|
||||||
} else {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
taskCompleted.set(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
decrementActiveGcmCount();
|
|
||||||
Log.i(TAG, "Processing complete.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!foregroundRunning.get()) {
|
|
||||||
new Thread("FcmForegroundServiceTimer") {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Util.sleep(7000);
|
|
||||||
synchronized (foregroundLock) {
|
|
||||||
if (!taskCompleted.get() && !foregroundRunning.getAndSet(true)) {
|
|
||||||
Log.i(TAG, "Starting a foreground task because the job is running long.");
|
|
||||||
showForegroundNotification(context);
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
latch.await();
|
messageReceiver.setSoTimeoutMillis(SOCKET_TIMEOUT);
|
||||||
} catch (InterruptedException e) {
|
new PushNotificationReceiveJob(context).pullAndProcessMessages(messageReceiver, TAG, startTime);
|
||||||
Log.w(TAG, "Latch was interrupted.", e);
|
} catch (IOException e) {
|
||||||
|
if (Build.VERSION.SDK_INT >= 26) {
|
||||||
|
Log.i(TAG, "Failed to retrieve the envelope. Scheduling on the system JobScheduler (API " + Build.VERSION.SDK_INT + ").", e);
|
||||||
|
FcmJobService.schedule(context);
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "Failed to retrieve the envelope. Scheduling on JobManager (API " + Build.VERSION.SDK_INT + ").", e);
|
||||||
|
ApplicationContext.getInstance(context)
|
||||||
|
.getJobManager()
|
||||||
|
.add(new PushNotificationReceiveJob(context));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void showForegroundNotification(@NonNull Context context) {
|
decrementActiveGcmCount();
|
||||||
GenericForegroundService.startForegroundTask(context,
|
Log.i(TAG, "Processing complete.");
|
||||||
context.getString(R.string.GcmBroadcastReceiver_retrieving_a_message),
|
|
||||||
NotificationChannels.OTHER,
|
|
||||||
R.drawable.ic_signal_downloading);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized boolean incrementActiveGcmCount() {
|
private static synchronized boolean incrementActiveGcmCount() {
|
||||||
|
@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.jobmanager.Data;
|
|||||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
|
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||||
@ -61,6 +62,7 @@ public class PushNotificationReceiveJob extends PushReceivedJob implements Injec
|
|||||||
Log.i(tag, "Successfully processed an envelope." + timeSuffix(startTime));
|
Log.i(tag, "Successfully processed an envelope." + timeSuffix(startTime));
|
||||||
});
|
});
|
||||||
TextSecurePreferences.setNeedsMessagePull(context, false);
|
TextSecurePreferences.setNeedsMessagePull(context, false);
|
||||||
|
MessageNotifier.cancelMessagesPending(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,6 +38,7 @@ import androidx.core.app.NotificationCompat;
|
|||||||
import androidx.core.app.NotificationManagerCompat;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||||
import org.thoughtcrime.securesms.contactshare.ContactUtil;
|
import org.thoughtcrime.securesms.contactshare.ContactUtil;
|
||||||
@ -120,7 +121,7 @@ public class MessageNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void notifyMessagesPending(Context context) {
|
public static void notifyMessagesPending(Context context) {
|
||||||
if (!TextSecurePreferences.isNotificationsEnabled(context)) {
|
if (!TextSecurePreferences.isNotificationsEnabled(context) || ApplicationContext.getInstance(context).isAppVisible()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +129,10 @@ public class MessageNotifier {
|
|||||||
ServiceUtil.getNotificationManager(context).notify(PENDING_MESSAGES_ID, builder.build());
|
ServiceUtil.getNotificationManager(context).notify(PENDING_MESSAGES_ID, builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void cancelMessagesPending(Context context) {
|
||||||
|
ServiceUtil.getNotificationManager(context).cancel(PENDING_MESSAGES_ID);
|
||||||
|
}
|
||||||
|
|
||||||
public static void cancelDelayedNotifications() {
|
public static void cancelDelayedNotifications() {
|
||||||
executor.cancel();
|
executor.cancel();
|
||||||
}
|
}
|
||||||
|
@ -23,14 +23,16 @@ public class PendingMessageNotificationBuilder extends AbstractNotificationBuild
|
|||||||
setColor(context.getResources().getColor(R.color.textsecure_primary));
|
setColor(context.getResources().getColor(R.color.textsecure_primary));
|
||||||
setCategory(NotificationCompat.CATEGORY_MESSAGE);
|
setCategory(NotificationCompat.CATEGORY_MESSAGE);
|
||||||
|
|
||||||
setContentTitle(context.getString(R.string.MessageNotifier_pending_signal_messages));
|
setContentTitle(context.getString(R.string.MessageNotifier_you_may_have_new_messages));
|
||||||
setContentText(context.getString(R.string.MessageNotifier_you_have_pending_signal_messages));
|
setContentText(context.getString(R.string.MessageNotifier_open_signal_to_check_for_recent_notifications));
|
||||||
setTicker(context.getString(R.string.MessageNotifier_you_have_pending_signal_messages));
|
setTicker(context.getString(R.string.MessageNotifier_open_signal_to_check_for_recent_notifications));
|
||||||
|
|
||||||
setContentIntent(PendingIntent.getActivity(context, 0, intent, 0));
|
setContentIntent(PendingIntent.getActivity(context, 0, intent, 0));
|
||||||
setAutoCancel(true);
|
setAutoCancel(true);
|
||||||
setAlarms(null, RecipientDatabase.VibrateState.DEFAULT);
|
setAlarms(null, RecipientDatabase.VibrateState.DEFAULT);
|
||||||
|
|
||||||
|
setOnlyAlertOnce(true);
|
||||||
|
|
||||||
if (!NotificationChannels.supported()) {
|
if (!NotificationChannels.supported()) {
|
||||||
setPriority(TextSecurePreferences.getNotificationPriority(context));
|
setPriority(TextSecurePreferences.getNotificationPriority(context));
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.util;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
|
import android.app.job.JobScheduler;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
@ -54,6 +55,11 @@ public class ServiceUtil {
|
|||||||
return (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
|
return (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(26)
|
||||||
|
public static JobScheduler getJobScheduler(Context context) {
|
||||||
|
return (JobScheduler) context.getSystemService(JobScheduler.class);
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
|
||||||
public static @Nullable SubscriptionManager getSubscriptionManager(@NonNull Context context) {
|
public static @Nullable SubscriptionManager getSubscriptionManager(@NonNull Context context) {
|
||||||
return (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
|
return (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user