当用户杀死应用程序时,前台服务崩溃并重新启动(牛轧糖)

问题描述 投票:0回答:1

我在这里遇到麻烦我想要一个前台服务应该运行,直到它的任务完成,一旦任务完成前台服务应该停止。但是这里的问题是即使它的Foreground Service服务在用户仅在Nougat版本中关闭应用程序时也会被杀死。我检查过Marshamallow,Oreo,Android派版本的情况正常。但在Nougat和MI手机中,这种情况无法正常工作。

以下是我作为演示运行的服务代码

public class MyForeGroundService  extends Service {
    private static final String TAG_FOREGROUND_SERVICE = "FOREGROUND_SERVICE";

    public static final String ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE";

    public static final String ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE";


    public static final String PRIMARY_CHANNEL = "default";

    public MyForeGroundService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG_FOREGROUND_SERVICE, "My foreground service onCreate().");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent != null)
        {
            String action = intent.getAction();

            switch (action)
            {
                case ACTION_START_FOREGROUND_SERVICE:
                    startForegroundService();
                    Toast.makeText(getApplicationContext(), "Foreground service is started.", Toast.LENGTH_LONG).show();
                    break;
                case ACTION_STOP_FOREGROUND_SERVICE:
                    stopForegroundService();
                    Toast.makeText(getApplicationContext(), "Foreground service is stopped.", Toast.LENGTH_LONG).show();
                    break;

            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    /* Used to build and start foreground service. */
    private void startForegroundService()
    {

        NotificationCompat.Builder mBuilder = notificationBuilder();
        // Start foreground service.
        startForeground(1, mBuilder.build());


        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent();
                intent.setAction("SERVICE_CONNECTED");
                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

            }
        },10000);
    }

    private void stopForegroundService()
    {
        Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");

        // Stop foreground service and remove the notification.
        stopForeground(true);

        // Stop the foreground service.
        stopSelf();
    }



    public NotificationCompat.Builder  notificationBuilder(){
        NotificationCompat.Builder mBuilder=  new NotificationCompat.Builder(this, PRIMARY_CHANNEL)
                .setContentTitle("Dummy Title")
                .setContentText("Dummy Message")
                .setStyle(new NotificationCompat.BigTextStyle()
                        .bigText("Big text Message"
                        ))
                .setPriority(NotificationCompat.PRIORITY_DEFAULT);

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mBuilder.setSmallIcon(R.drawable.app_icon_white);
            mBuilder.setColor(getResources().getColor(R.color.theme_color));
        } else {
            mBuilder.setSmallIcon(R.drawable.app_icon_white);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getResources().getString(R.string.feroz_channel_name);
            String description = getResources().getString(R.string.feroz_channel_description);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(PRIMARY_CHANNEL, name, importance);
            channel.enableLights(true);
            channel.setLightColor(getResources().getColor(R.color.theme_color));
            channel.enableVibration(true);
            channel.setDescription(description);

            NotificationManager notificationManager1 = getSystemService(NotificationManager.class);
            notificationManager1.createNotificationChannel(channel);
        }


        Intent stopIntent = new Intent(this, MyForeGroundService.class);
        stopIntent.setAction(ACTION_STOP_FOREGROUND_SERVICE);
        PendingIntent stopPlayIntent = PendingIntent.getService(this, 0, stopIntent, 0);
        mBuilder.addAction(R.drawable.ic_launcher_new,"STOP",stopPlayIntent);
        Intent intent = new Intent(this, CreateForegroundServiceActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,  PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(pendingIntent);
         mBuilder.setUsesChronometer(true);

        return mBuilder;
    }
}

以下是从活动开始服务的代码

startServiceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(CreateForegroundServiceActivity.this, MyForeGroundService.class);
                intent.setAction(MyForeGroundService.ACTION_START_FOREGROUND_SERVICE);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    startForegroundService(intent);
                } else {
                    startService(intent);
                }          
            }
        });

        Button stopServiceButton = (Button)findViewById(R.id.stop_foreground_service_button);
        stopServiceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(CreateForegroundServiceActivity.this, MyForeGroundService.class);
                intent.setAction(MyForeGroundService.ACTION_STOP_FOREGROUND_SERVICE);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    startForegroundService(intent);
                } else {
                    startService(intent);
                } 
            }
        });

我认为startForeGroundService工作正常,但startService没有按预期工作。行为是如此令人困惑,当我杀死应用程序前台服务重新启动,但如果我打开应用程序并按下按钮停止服务我可以看到发送到服务的意图。但是服务仍在运行。

This is lenovo Phone on which Service get restarted

PS:我想要一个运行10分钟的服务,无论App是否在后台。它不应该不惜任何代价重新启动。例如,如果我正在播放背景音乐,它应该播放到最后。它应该在音乐结束后立即停止。我不希望它重新启动下面是日志,当我按钮点击启动服务并杀死应用程序:

2019-02-15 13:35:56.091 11120-11120/sample.androido.com.myapplication D/MyForeGroundService: My foreground service onCreate().
2019-02-15 13:36:01.956 1459-3975/? W/ActivityManager: Scheduling restart of crashed service sample.androido.com.myapplication/.services.MyForeGroundService in 1000ms
2019-02-15 13:36:02.975 1459-1509/? I/ActivityManager: Start proc 11170:sample.androido.com.myapplication/u0a154 for service sample.androido.com.myapplication/.services.MyForeGroundService
2019-02-15 13:36:03.674 11170-11170/? D/MyForeGroundService: My foreground service onCreate().
android service foreground-service
1个回答
1
投票

来自官方Android documentationstartForegroundService()方法。

请注意,调用此方法不会将服务置于启动状态本身,即使名称听起来像它。您必须首先调用ContextWrapper.startService(Intent)告诉系统它应该保持服务运行,然后使用此方法告诉它让它更难运行。

根据上面的陈述,你应该先调用startService()然后再调用startForegroundService()

© www.soinside.com 2019 - 2024. All rights reserved.