Служба Foreground Crash и перезапуск, когда Пользователь убил приложение (Nougat) - PullRequest
0 голосов
/ 15 февраля 2019

У меня возникла проблема, когда я хочу, чтобы служба переднего плана работала до тех пор, пока ее задача не будет завершена, и как только задача будет завершена, служба переднего плана должна остановиться.Но проблема здесь в том, что даже если его Служба Foreground Service будет убита, когда пользователь закроет приложение только в Nougat Version.Я проверил 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 минут независимо от того, находится приложение в фоновом режиме или нет.Это не должно быть Перезапущено любой ценой.Например, если я играю музыку из фона, она должна играть до конца.это должно прекратиться, как только закончится музыка.Я не хочу, чтобы он был перезапущен. Ниже приведены журналы, когда я запускаю службу по нажатию кнопки и убиваю приложение:

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().

1 Ответ

0 голосов
/ 15 февраля 2019

Из официальной документации Android для startForegroundService() метода.

Обратите внимание, что вызов этого метода не переводит службу в запущенное состояние, даже если имя звучитнравится.Вы всегда должны сначала вызывать ContextWrapper.startService (Intent), чтобы сообщить системе, что она должна поддерживать службу, а затем использовать этот метод, чтобы заставить ее работать тяжелее.

Согласно приведенному выше утверждениюВы должны сначала позвонить startService(), а затем startForegroundService()

...