Неустранимое исключение: android .app.RemoteServiceException Context.startForegroundService () не вызывало Service.startForeground () - PullRequest
2 голосов
/ 14 апреля 2020

Мы недавно внедрили службу переднего плана и на Android 9 (только на устройствах Samsung) некоторые пользователи испытывают некоторые повторяющиеся сбои, и мы не знаем, что является причиной этого. Кто-нибудь сталкивался с такой же проблемой? Есть ли исправление для этой проблемы?

Fatal Exception: android.app.RemoteServiceException Context.startForegroundService() did not then call Service.startForeground()
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1874)
android.os.Handler.dispatchMessage (Handler.java:106)
android.os.Looper.loop (Looper.java:214)
android.app.ActivityThread.main (ActivityThread.java:7073)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:964)

AndroidManigest. xml

<service
        android:name="com.sotg.base.util.GeoNotification"
        android:exported="true"
        android:foregroundServiceType="location" />

GeoNotificationManager.kt

    override fun startService() {
        val geoService = Intent(context, GeoNotification::class.java)
        geoService.action = GeoNotification.START_SERVICE_ACTION

        // for android Oreo and higher start as foreground
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(geoService)
        } else {
            context.startService(geoService)
        }
    }

    override fun stopService() {

        // Shouldn't initialize the service to stop it when the service is not running.
        if (!GeoNotification.isServiceRunning()) return;

        val geoService = Intent(context, GeoNotification::class.java)
        geoService.action = GeoNotification.STOP_TRACKING_ACTION
        runCatching { context.startService(geoService) }
                .onFailure(analytics::logException)
    }

GoeNotification. java

    private static boolean isServiceRunning;

    public static boolean isServiceRunning() {
        return isServiceRunning;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        isServiceRunning = false;
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (START_SERVICE_ACTION.equals(intent.getAction())) {
            startTracking();
        } else if (STOP_TRACKING_ACTION.equals(intent.getAction())) {
            stopTracking();
        } else {
            Log.w(TAG, "Unknown action for location service");
        }

        // Service restarts if it gets terminated
        // the original Intent is re-delivered to the onStartCommand
        // method when using START_REDELIVER_INTENT.
        return START_REDELIVER_INTENT;
    }

 private void startTracking() {

        if (isServiceRunning) return;

        // create notification and config as foreground only for android Oreo and higher
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForeground(Constants.NOTIFY_SURVEY_GCM, createForegroundNotification(this));
        }

        isServiceRunning = true;

       ...
    }

    private void stopTracking() {

        if (!isServiceRunning) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                stopForeground(true);
            }
            stopSelf();
            return;
        }

        // stop location updates on partner SDKs
       ....
        stopSelf();
        isServiceRunning = false;
    }

    public static Notification createForegroundNotification(Context context) {
            NotificationChannelUtil.INSTANCE.getPreparedManager(context);
            String channel = NotificationChannelUtil.INSTANCE.getSYSTEM_CHANNEL_ID();

            // The PendingIntent to launch activity.
            PendingIntent activityPendingIntent = PendingIntent.getActivity(context, 0,
                    new Intent(context, MainTabActivity.class), 0);

            NotificationCompat.Action settingsAction = NotificationUtil.createSettingAction(context);

            String title = context.getResources().getString(R.string.foreground_service_notification_title);
            String desc = context.getResources().getString(R.string.foreground_service_notification_description);
            String expandedText = context.getResources().getString(R.string.foreground_service_notification_description_expanded);

            NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channel)
                    .setContentIntent(activityPendingIntent)
                    .setSmallIcon(R.drawable.noti)
                    .setContentTitle(title)
                    .setContentText(desc)
                    .setStyle(new NotificationCompat.BigTextStyle()
                            .bigText(expandedText))
                    .addAction(settingsAction)
                    .setColorized(false)
                    .setOngoing(true);

            return builder.build();
        }

1 Ответ

1 голос
/ 15 апреля 2020

У меня была такая же проблема с устройствами Samsung и Huawei с Android Oreo или выше. Я получил бы те же ошибки.

Если я правильно помню, поскольку Android Oreo и выше необходимо использовать startForeground() при использовании startService() или startForegroundService().

Я решил это, добавив следующий код в функцию onCreate класса обслуживания. Я создал уведомление и запустил его с startForeground().

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    NotificationChannel mNotificationChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_NONE);
    mNotificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    mNotificationManager.createNotificationChannel(mNotificationChannel);
    Notification note = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Reboot Sequence")
            .setContentText("Rescheduling Alarms")
            .setSmallIcon(R.drawable.ic_alarm_24dp)
            .build();
    startForeground(1, note);
}

Надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...