应用程序关闭后无法使android服务保持活动状态

gmm*_*mmo 11 android android-service

我正在尝试生成一个始终保持活动的服务,即使用户关闭了应用程序.根据这些线程

关闭应用程序后,保持位置服务活动

应用程序关闭时Android服务停止

Android:当应用程序被杀时,保持服务运行

这可以通过IntentServices或Service.START_STICKY来完成

然而,我尝试了两种类型的服务而没有成功.换句话说,当用户关闭应用程序时,我的服务就会被杀死.有人可以指出这是否可以做到以及如何做?这是我没有成功的尝试:

使用IntentService:

public class MyIntentService extends IntentService {
    private final int mPollingTimeMS = 500;
    private int mInitializationPollingCount = 0;
    private Thread mPollThread;
    public MyIntentService() {
        super("MyIntentService");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        mPollThread = new Thread() {
            public void run() {
                while (true) {
                    try {
                        Log.e(Constants.Engine.LOGGER_TAG_DEV,
                                "SDK Service Running: " +
                                        mInitializationPollingCount * mPollingTimeMS +
                                        "ms have elapsed");
                        mInitializationPollingCount++;
                        sleep(mPollingTimeMS);

                    } catch (Exception e) {
                        StackTraceElement trace = new Exception().getStackTrace()[0];
                        Logger.e(Constants.Engine.LOGGER_TAG_APP, "[Exception:" + e.toString() + "]" +
                                trace.getClassName() + "->" + trace.getMethodName() + ":" + trace.getLineNumber());
                    }
                }
            }
        };
        mPollThread.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

和服务:

public class MyService extends Service {
    public MyService() {
    }
    private final int mPollingTimeMS = 500;
    private int mInitializationPollingCount = 0;
    private Thread mPollThread;
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mPollThread = new Thread() {
            public void run() {
                while (true) {
                    try {
                        Log.e(Constants.Engine.LOGGER_TAG_DEV,
                                "SDK Service Running: " +
                                        mInitializationPollingCount * mPollingTimeMS +
                                        "ms have elapsed");
                        mInitializationPollingCount++;
                        sleep(mPollingTimeMS);

                    } catch (Exception e) {
                        StackTraceElement trace = new Exception().getStackTrace()[0];
                        Logger.e(Constants.Engine.LOGGER_TAG_APP, "[Exception:" + e.toString() + "]" +
                                trace.getClassName() + "->" + trace.getMethodName() + ":" + trace.getLineNumber());
                    }
                }
            }
        };
        mPollThread.start();
        return Service.START_STICKY;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // I tried to return null here, but this
        // service gets killed no matter what.
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是清单:

    <service
        android:name=".mycompany.MyService"
        android:enabled="true"
        android:exported="true"
        android:process=":process1">
    </service>
    <service
        android:name=".mycompany.MyIntentService"
        android:process=":process2"
        android:exported="false">
    </service>
Run Code Online (Sandbox Code Playgroud)

我将补充说,我正在关闭测试应用程序而不是关闭按钮,而是使用Android OS应用程序管理器.见下图

在此输入图像描述

最后,司机活动(那里不多)

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent1 = new Intent(getBaseContext(), MyService.class);
        startService(intent1);
        Intent intent2 = new Intent(getBaseContext(), MyIntentService.class);
        startService(intent2);

    }
}
Run Code Online (Sandbox Code Playgroud)

我还尝试添加通知并使其成为前台服务,但仍然是相同的.关闭应用程序的那一刻,一切都被杀死了.这就是我添加的内容:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    showNotification();
...etc..

private void showNotification() {
    Intent notificationIntent = new Intent(this, MainActivity.class);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
            notificationIntent, 0);
    int iconId = R.mipmap.ic_launcher;
    int uniqueCode = new Random().nextInt(Integer.MAX_VALUE);
    Notification notification = new NotificationCompat.Builder(this)
            .setSmallIcon(iconId)
            .setContentText("Context Text")
            .setContentIntent(pendingIntent).build();
    startForeground(uniqueCode, notification);
}
Run Code Online (Sandbox Code Playgroud)

Bep*_*i's 14

这是我使用的前台服务的一个示例,它可以正常工作,它在应用程序关闭时保持活动状态.当然,它也必须启动,对于该任务,应用程序必须乍一看,或者必须设置启动事件的接收器,但这是另一个故事.

public class MyService extends Service {
static final int NOTIFICATION_ID = 543;

public static boolean isServiceRunning = false;

@Override
public void onCreate() {
    super.onCreate();
    startServiceWithNotification();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null && intent.getAction().equals(C.ACTION_START_SERVICE)) {
        startServiceWithNotification();
    }
    else stopMyService();
    return START_STICKY;
}

// In case the service is deleted or crashes some how
@Override
public void onDestroy() {
    isServiceRunning = false;
    super.onDestroy();
}

@Override
public IBinder onBind(Intent intent) {
    // Used only in case of bound services.
    return null;
}


void startServiceWithNotification() {
    if (isServiceRunning) return;
    isServiceRunning = true;

    Intent notificationIntent = new Intent(getApplicationContext(), MyActivity.class);
    notificationIntent.setAction(C.ACTION_MAIN);  // A string containing the action name
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent contentPendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

    Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.my_icon);

    Notification notification = new NotificationCompat.Builder(this)
            .setContentTitle(getResources().getString(R.string.app_name))
            .setTicker(getResources().getString(R.string.app_name))
            .setContentText(getResources().getString(R.string.my_string))
            .setSmallIcon(R.drawable.my_icon)
            .setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
            .setContentIntent(contentPendingIntent)
            .setOngoing(true)
//                .setDeleteIntent(contentPendingIntent)  // if needed
            .build();
    notification.flags = notification.flags | Notification.FLAG_NO_CLEAR;     // NO_CLEAR makes the notification stay when the user performs a "delete all" command
    startForeground(NOTIFICATION_ID, notification);
}

void stopMyService() {
    stopForeground(true);
    stopSelf();
    isServiceRunning = false;
}
}
Run Code Online (Sandbox Code Playgroud)

然后我运行它

    Intent startIntent = new Intent(getApplicationContext(), MyService.class);
    startIntent.setAction(C.ACTION_START_SERVICE);
    startService(startIntent);
Run Code Online (Sandbox Code Playgroud)

请注意用作Actions的两个常量,这些是必须以包名开头的字符串.

  • C.ACTION_START_SERVICE中的"C"是什么 (9认同)
  • Android 8.1:它不起作用。也许问题出在我的手机(SMJ610)上。它没有按预期工作。当我启动应用程序时,它会启动应该创建服务的命令序列,并运行该命令。我在通知栏中看到通知,甚至无法删除它(很好)。但是一旦我关闭应用程序,通知就会被删除并且音乐停止(我正在制作音频播放器)。 (2认同)

Mik*_*ren 5

IntentService

使用IntentService可能不是最好的方法.默认情况下,IntentServiceonHandleIntent(Intent)返回后自行停止,并且没有剩下的工作要做(即请求队列为空).这在IntentService官方文档中有解释:

处理完所有请求后,IntentService会自行停止,因此不应调用stopSelf().

在您的情况下,onHandleIntent(Intent)创建一个线程但立即返回,这使它自行停止.

服务+ startForeground()

Service只要您在单独的进程上运行该服务,就应该使用常规的前台模式.为此,您需要:

  1. 使onStartCommand()回报START_STICKY.
  2. 调用方法以显示通知onCreate().
  3. 在单独的进程中运行该服务(使用android:process=":something").

根据这篇文章,您似乎已经单独尝试了其中一些步骤,但从未尝试过所有这些步骤.


归档时间:

查看次数:

26920 次

最近记录:

6 年,4 月 前