Oreo - службы виджетов и приемник вещания: запуск службы не разрешен

У меня есть виджет, который контролирует подключение к Wi-Fi, поэтому я запускаю службу для запуска широковещательного приемника для обнаружения изменений в сети. Все работает хорошо, за исключением, когда я выхожу из основного приложения: служба останавливается.

Поэтому я запускаю в виджете Диспетчер тревог, который просыпается примерно каждую минуту и ​​проверяет, закрылось ли основное приложение. Если это так, я пытаюсь перезапустить службу мониторинга Wi-Fi, и на этот раз она вылетает с сообщением:

Запрещено запускать службу. Intent {cmp =package.CallbackNetworkWidgetService (имеет дополнительные функции) }: приложение находится в фоновом режиме.

Проблема связана с новой моделью намерений / услуг. Работает до нуга.

Вопросы:

  1. мой подход правильный?

  2. Я немного растерялся с понятием переднего плана / фонового обслуживания. Виджет это фон SVCE? Служба мониторинга WiFi /BR также является фоновым SVCE?

  3. В чем здесь проблема?

Manifest:

<receiver android:name=".Widget.TestWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <intent-filter>
                <action android:name="AUTO_UPDATE" />
            </intent-filter>
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/test_widget_info" />
        </receiver>

        <service android:name=".Widget.CallbackNetworkWidgetService"></service>

CallbackWidgetNetworkService

@Override
public int onStartCommand(Intent i, int flags, int startId) {
    context = this.getApplicationContext();
    Log.i("WIDNET", "onStart network");

    isWifiConnected();

    return Service.START_NOT_STICKY;
}

public void isWifiConnected(){

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            getNetworkInfo();
          //  Log.i("WIDNET", "broadcastReceiver ipwan: "+ipwan+" type: "+type);
        }
    };

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);

    context.registerReceiver(broadcastReceiver, intentFilter);
}

Appwidget - startNetworkService

 public static void startNetworkService(Context context){
        int[] allWidgetIds = new int[0];

        Log.i("WIDNET", "start network service");
        ComponentName thisWidget = new ComponentName(context,
                TestWidget.class);
        if(widgetManager != null)
            allWidgetIds = widgetManager.getAppWidgetIds(thisWidget);

        if(intentNetwork != null) {
            CallbackNetworkWidgetService cnws = new CallbackNetworkWidgetService();
            cnws.stopSelf();
            Log.i("WIDNET", "stop network service");
        }

        intentNetwork = new Intent(context.getApplicationContext(),
                CallbackNetworkWidgetService.class);
        intentNetwork.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

        context.startService(intentNetwork);
    }

1 ответ

Решение

Вы должны использовать приоритетный сервис для этой цели.

ContextCompat.startForegroundService(context, intentNetwork);

Не забудьте для уведомления для API 26+:

@Override
public int onStartCommand(Intent i, int flags, int startId) {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID)
            .setContentTitle("wifi listener bla bla bla")
            .setContentText(text)
            .setAutoCancel(true);

      Notification notification = builder.build();
      startForeground(1, notification);
   }
   //...
}
Другие вопросы по тегам