Oreo - службы виджетов и приемник вещания: запуск службы не разрешен
У меня есть виджет, который контролирует подключение к Wi-Fi, поэтому я запускаю службу для запуска широковещательного приемника для обнаружения изменений в сети. Все работает хорошо, за исключением, когда я выхожу из основного приложения: служба останавливается.
Поэтому я запускаю в виджете Диспетчер тревог, который просыпается примерно каждую минуту и проверяет, закрылось ли основное приложение. Если это так, я пытаюсь перезапустить службу мониторинга Wi-Fi, и на этот раз она вылетает с сообщением:
Запрещено запускать службу. Intent {cmp =package.CallbackNetworkWidgetService (имеет дополнительные функции) }: приложение находится в фоновом режиме.
Проблема связана с новой моделью намерений / услуг. Работает до нуга.
Вопросы:
мой подход правильный?
Я немного растерялся с понятием переднего плана / фонового обслуживания. Виджет это фон SVCE? Служба мониторинга WiFi /BR также является фоновым SVCE?
В чем здесь проблема?
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);
}
//...
}