Skip to content

Start service with start foregroundService on Android Oreo #1786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@

import org.renpy.android.Hardware;

import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.Manifest;
import android.app.NotificationChannel;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.support.v4.app.NotificationCompat;
import android.graphics.Color;
import android.app.Service;
import android.content.ComponentName;
import android.app.PendingIntent;

import android.graphics.drawable.Icon;
import android.provider.Settings;

public class PythonService extends Service implements Runnable {

Expand All @@ -35,6 +50,7 @@ public class PythonService extends Service implements Runnable {
private String pythonServiceArgument;
public static PythonService mService = null;
private Intent startIntent = null;
private String NOTIFICATION_CHANNEL_ID = "BackgroundService";

private boolean autoRestartService = false;

Expand Down Expand Up @@ -67,8 +83,13 @@ public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}

startIntent = intent;
startIntent = intent;
Bundle extras = intent.getExtras();

if (canDisplayNotification()) {
doStartForeground(extras);
}

androidPrivate = extras.getString("androidPrivate");
androidArgument = extras.getString("androidArgument");
serviceEntrypoint = extras.getString("serviceEntrypoint");
Expand All @@ -80,10 +101,6 @@ public int onStartCommand(Intent intent, int flags, int startId) {
pythonThread = new Thread(this);
pythonThread.start();

if (canDisplayNotification()) {
doStartForeground(extras);
}

return startType();
}

Expand All @@ -96,6 +113,7 @@ protected void doStartForeground(Bundle extras) {
Intent contextIntent = new Intent(context, PythonActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, contextIntent,
PendingIntent.FLAG_UPDATE_CURRENT);

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
notification = new Notification(
context.getApplicationInfo().icon, serviceTitle, System.currentTimeMillis());
Expand All @@ -108,6 +126,25 @@ protected void doStartForeground(Bundle extras) {
} catch (NoSuchMethodException | IllegalAccessException |
IllegalArgumentException | InvocationTargetException e) {
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelName = "Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_MIN);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);

NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, "persistent");
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(context.getApplicationInfo().icon)
.setContentTitle(serviceTitle)
.setContentIntent(pIntent)
.setPriority(Notification.PRIORITY_MIN)
.setShowWhen(false)
.setOnlyAlertOnce(true)
.build();
} else {
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle(serviceTitle);
Expand All @@ -127,17 +164,14 @@ public void onDestroy() {
Log.v("python service", "service restart requested");
startService(startIntent);
}
Process.killProcess(Process.myPid());
}

/**
* Stops the task gracefully when killed.
* Calling stopSelf() will trigger a onDestroy() call from the system.
* Stops the task gracefully, but don t kill the process.
*/
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
stopSelf();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,23 @@
import org.kivy.android.PythonService;
import org.kivy.android.PythonActivity;

import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.Manifest;
import android.app.NotificationChannel;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.support.v4.app.NotificationCompat;
import android.graphics.Color;
import android.app.Service;
import android.content.ComponentName;
import android.app.PendingIntent;

public class Service{{ name|capitalize }} extends PythonService {

private boolean autoRestartService = true;

{% if sticky %}
@Override
public int startType() {
Expand Down Expand Up @@ -46,14 +61,33 @@ protected void doStartForeground(Bundle extras) {
} catch (NoSuchMethodException | IllegalAccessException |
IllegalArgumentException | InvocationTargetException e) {
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelName = "{{ name| capitalize }}";
NotificationChannel chan = new NotificationChannel("{{ args.name }}", channelName, NotificationManager.IMPORTANCE_MIN);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);

NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, "{{ args.name }}");
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(context.getApplicationInfo().icon)
.setContentTitle(channelName)
.setContentIntent(pIntent)
.setPriority(Notification.PRIORITY_MIN)
.setShowWhen(false)
.setOnlyAlertOnce(true)
.build();
} else {
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle("{{ args.name }}");
builder.setContentText("{{ name| capitalize }}");
builder.setContentIntent(pIntent);
builder.setSmallIcon(context.getApplicationInfo().icon);
notification = builder.build();
}
}
startForeground({{ service_id }}, notification);
}

Expand All @@ -67,9 +101,20 @@ static public void start(Context ctx, String pythonServiceArgument) {
intent.putExtra("pythonHome", argument);
intent.putExtra("pythonPath", argument + ":" + argument + "/lib");
intent.putExtra("pythonServiceArgument", pythonServiceArgument);
ctx.startService(intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ctx.startForegroundService(intent);
} else {
ctx.startService(intent);
}
}


@Override
public void onDestroy() {
super.onDestroy();
}


static public void stop(Context ctx) {
Intent intent = new Intent(ctx, Service{{ name|capitalize }}.class);
ctx.stopService(intent);
Expand Down