mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
130 lines
5.1 KiB
Java
130 lines
5.1 KiB
Java
package org.thoughtcrime.securesms.connect;
|
|
|
|
import android.annotation.TargetApi;
|
|
import android.app.Notification;
|
|
import android.app.NotificationChannel;
|
|
import android.app.NotificationManager;
|
|
import android.app.PendingIntent;
|
|
import android.app.Service;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.os.Build;
|
|
import android.os.IBinder;
|
|
import android.util.Log;
|
|
|
|
import androidx.core.app.NotificationCompat;
|
|
import androidx.core.content.ContextCompat;
|
|
|
|
import org.thoughtcrime.securesms.ConversationListActivity;
|
|
import org.thoughtcrime.securesms.R;
|
|
import org.thoughtcrime.securesms.notifications.NotificationCenter;
|
|
import org.thoughtcrime.securesms.util.IntentUtils;
|
|
import org.thoughtcrime.securesms.util.Prefs;
|
|
|
|
public class KeepAliveService extends Service {
|
|
|
|
private static final String TAG = KeepAliveService.class.getSimpleName();
|
|
|
|
static KeepAliveService s_this = null;
|
|
|
|
public static void maybeStartSelf(Context context) {
|
|
// note, that unfortunately, the check for isIgnoringBatteryOptimizations() is not sufficient,
|
|
// this checks only stock-android settings, several os have additional "optimizers" that ignore this setting.
|
|
// therefore, the most reliable way to not get killed is a permanent-foreground-notification.
|
|
if (Prefs.reliableService(context)) {
|
|
startSelf(context);
|
|
}
|
|
}
|
|
|
|
public static void startSelf(Context context)
|
|
{
|
|
try {
|
|
ContextCompat.startForegroundService(context, new Intent(context, KeepAliveService.class));
|
|
}
|
|
catch(Exception e) {
|
|
Log.i(TAG, "Error calling ContextCompat.startForegroundService()", e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCreate() {
|
|
Log.i("DeltaChat", "*** KeepAliveService.onCreate()");
|
|
// there's nothing more to do here as all initialisation stuff is already done in
|
|
// ApplicationLoader.onCreate() which is called before this broadcast is sended.
|
|
s_this = this;
|
|
|
|
// set self as foreground
|
|
try {
|
|
stopForeground(true);
|
|
startForeground(NotificationCenter.ID_PERMANENT, createNotification());
|
|
}
|
|
catch (Exception e) {
|
|
Log.i(TAG, "Error in onCreate()", e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
// START_STICKY ensured, the service is recreated as soon it is terminated for any reasons.
|
|
// as ApplicationLoader.onCreate() is called before a service starts, there is no more to do here,
|
|
// the app is just running fine.
|
|
Log.i("DeltaChat", "*** KeepAliveService.onStartCommand()");
|
|
return START_STICKY;
|
|
}
|
|
|
|
@Override
|
|
public IBinder onBind(Intent intent) {
|
|
return null;
|
|
}
|
|
|
|
public void onDestroy() {
|
|
Log.i("DeltaChat", "*** KeepAliveService.onDestroy()");
|
|
// the service will be restarted due to START_STICKY automatically, there's nothing more to do.
|
|
}
|
|
|
|
static public KeepAliveService getInstance()
|
|
{
|
|
return s_this; // may be null
|
|
}
|
|
|
|
/* The notification
|
|
* A notification is required for a foreground service; and without a foreground service,
|
|
* ArcaneChat won't get new messages reliable
|
|
**********************************************************************************************/
|
|
|
|
private Notification createNotification()
|
|
{
|
|
Intent intent = new Intent(this, ConversationListActivity.class);
|
|
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | IntentUtils.FLAG_MUTABLE());
|
|
// a notification _must_ contain a small icon, a title and a text, see https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Required
|
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
|
|
|
|
builder.setContentTitle(getString(R.string.app_name));
|
|
builder.setContentText(getString(R.string.notify_background_connection_enabled));
|
|
|
|
builder.setPriority(NotificationCompat.PRIORITY_MIN);
|
|
builder.setWhen(0);
|
|
builder.setContentIntent(contentIntent);
|
|
builder.setSmallIcon(R.drawable.notification_permanent);
|
|
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
|
|
createFgNotificationChannel(this);
|
|
builder.setChannelId(NotificationCenter.CH_PERMANENT);
|
|
}
|
|
return builder.build();
|
|
}
|
|
|
|
private static boolean ch_created = false;
|
|
@TargetApi(Build.VERSION_CODES.O)
|
|
static private void createFgNotificationChannel(Context context) {
|
|
if(!ch_created) {
|
|
ch_created = true;
|
|
NotificationChannel channel = new NotificationChannel(NotificationCenter.CH_PERMANENT,
|
|
"Receive messages in background.", NotificationManager.IMPORTANCE_MIN); // IMPORTANCE_DEFAULT will play a sound
|
|
channel.setDescription("Ensure reliable message receiving.");
|
|
channel.setShowBadge(false);
|
|
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
|
|
notificationManager.createNotificationChannel(channel);
|
|
}
|
|
}
|
|
}
|