Use startServiceForeground() on Android 8 (fixes #963)

This commit is contained in:
Felix Ableitner 2017-10-10 15:59:22 +09:00
parent cefd9dcfc0
commit 4941d7e412
6 changed files with 42 additions and 10 deletions

View File

@ -31,7 +31,7 @@ public class BatteryReceiver extends BroadcastReceiver {
lbm.sendBroadcast(i);
// Make sure service is running.
context.startService(new Intent(context, SyncthingService.class));
BootReceiver.startServiceCompat(context);
}
/**

View File

@ -3,6 +3,7 @@ package com.nutomic.syncthingandroid.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import com.nutomic.syncthingandroid.service.SyncthingService;
@ -17,6 +18,21 @@ public class BootReceiver extends BroadcastReceiver {
if (!SyncthingService.alwaysRunInBackground(context))
return;
context.startService(new Intent(context, SyncthingService.class));
startServiceCompat(context);
}
/**
* Workaround for starting service from background on Android 8.
*
* https://stackoverflow.com/a/44505719/1837158
*/
public static void startServiceCompat(Context context) {
Intent intent = new Intent(context, SyncthingService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
}
else {
context.startService(intent);
}
}
}

View File

@ -8,7 +8,6 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
import com.nutomic.syncthingandroid.service.SyncthingService;
@ -45,7 +44,7 @@ public class NetworkReceiver extends BroadcastReceiver {
lbm.sendBroadcast(intent);
// Make sure service is running.
context.startService(new Intent(context, SyncthingService.class));
BootReceiver.startServiceCompat(context);
}
}

View File

@ -40,20 +40,31 @@ public class NotificationHandler {
public void updatePersistentNotification(SyncthingService service, SyncthingService.State currentState) {
String type = mPreferences.getString(Constants.PREF_NOTIFICATION_TYPE, "low_priority");
boolean foreground = mPreferences.getBoolean(Constants.PREF_FOREGROUND_SERVICE, false);
// Android 8 does not allow starting service from background unless it's a foreground
// service, so if "always run in background" is enabled, we have to use a foreground service.
// https://stackoverflow.com/a/44505719/1837158
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && SyncthingService.alwaysRunInBackground(mContext)) {
foreground = true;
}
// foreground priority requires any notification
// so this ensures that we either have a "default" or "low_priority" notification,
// but not "none".
if ("none".equals(type) && foreground) {
// foreground priority requires any notification
// so this ensures that we either have a "default" or "low_priority" notification,
// but not "none".
type = "low_priority";
}
if ((currentState == SyncthingService.State.ACTIVE || currentState == SyncthingService.State.STARTING) &&
!type.equals("none")) {
boolean syncthingRunning = currentState == SyncthingService.State.ACTIVE ||
currentState == SyncthingService.State.STARTING;
if (foreground || (syncthingRunning && !type.equals("none"))) {
// Launch FirstStartActivity instead of MainActivity so we can request permission if
// necessary.
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
new Intent(mContext, FirstStartActivity.class), 0);
int title = syncthingRunning ? R.string.syncthing_active : R.string.syncthing_disabled;
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
.setContentTitle(mContext.getString(R.string.syncthing_active))
.setContentTitle(mContext.getString(title))
.setSmallIcon(R.drawable.ic_stat_notify)
.setOngoing(true)
.setContentIntent(pi);
@ -74,6 +85,9 @@ public class NotificationHandler {
}
public void cancelPersistentNotification(SyncthingService service) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && SyncthingService.alwaysRunInBackground(mContext))
return;
service.stopForeground(false);
mNotificationManager.cancel(ID_PERSISTENT);
}

View File

@ -53,6 +53,7 @@ public class FoldersAdapter extends ArrayAdapter<Folder> {
binding.openFolder.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(folder.path)), "resource/folder");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
getContext().startActivity(intent);
} else {

View File

@ -519,6 +519,8 @@ Please report any problems you encounter via Github.</string>
<!-- Title of the notification shown while syncthing is running and enabled -->
<string name="syncthing_active">Syncthing is running</string>
<string name="syncthing_disabled">Syncthing is disabled</string>
<string name="syncthing_active_foreground">Service is running with foreground priority.</string>
<!-- Toast shown if folder observer fails to traverse a folder -->