Введение
Я использую flutter v1.17.5 DeviceApps v1.0.10 и SystemAlertWindow v0.2.2 + 3 (намеренно не последняя версия). И я хочу открыть свое приложение из окна системного предупреждения, которое работает на переднем плане, даже когда приложение закрыто.
Я использую плагин SystemOverlayWindow , и этот плагин является действием SystemAlertWindowPlugin. java
В моем Application.kt я регистрирую плагины и передаю реестр
public class Application: FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);
SystemAlertWindowPlugin.setPluginRegistrant(this);
createNotificationChannels();
FlutterMain.startInitialization(this);
}
override fun registerWith(registry: PluginRegistry?) {
if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) {
FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
if (!registry!!.hasPlugin("in.jvapps.system_alert_window")) {
SystemAlertWindowPlugin.registerWith(registry!!.registrarFor("in.jvapps.system_alert_window"));
}
if (!registry!!.hasPlugin("fr.g123k.deviceapps")) {
DeviceAppsPlugin.registerWith(registry!!.registrarFor("fr.g123k.deviceapps"));
}
}
Я также регистрирую еще один плагин называется DeviceApps . Это DeviceAppsPlugin DeviceAppsPlugin. java
Проблема
Короче
Итак, системный оверлей (который выполняется на переднем плане) вызывает> обратный вызов dart> вызывает метод плагина DeviceApps> возникает ошибка
Длинная версия
У меня есть статус c обратный вызов, который зарегистрирован здесь , и он вызывается, когда у меня есть щелчок при взаимодействии с окном системного предупреждения. Но теперь я не хочу вызывать плагин DeviceApps в моем коде дротика из этого stati c callback
Таким образом, канал метода вызовет this , и это запустит stati c обратный вызов, определенный в dart.
Это stati c обратный вызов dart, который регистрируется и вызывается с фоновым каналом
static Future<void> systemOverlayOnClickListner(String tag) async {
switch (tag) {
case 'button_app_to_foreground':
DeviceApps.openApp('com.companyname.appname'); // this is where I try to run the plugin
await SystemAlertWindow.closeSystemWindow();
break;
}
Обратный вызов вызывает метод подключаемого модуля DeviceApps. И это вызывает проблемы, потому что этот метод будет пытаться получить диспетчер пакетов из действия, переданного в его конструкторе. Но в соответствии с этой ошибкой активность равна нулю.
E/MethodChannel#g123k/device_apps(24210): Failed to handle method call
E/MethodChannel#g123k/device_apps(24210): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.PackageManager android.app.Activity.getPackageManager()' on a null object reference
E/MethodChannel#g123k/device_apps(24210): at fr.g123k.deviceapps.DeviceAppsPlugin.openApp(DeviceAppsPlugin.java:141)
Таким образом, она вызовет getPackageManager () для нулевого объекта.
Действие равно нулю только тогда, когда оно вызывается из этого stati c обратный вызов, который вызывается фоновым каналом. Но не тогда, когда я обычно вызываю это из области приложения. Почему это так?
Conslusion
Итак, в заключение вызов плагина работает нормально, когда я вызываю его из области своего приложения. Но как только обратный вызов вызывается средствами фонового канала, активность внезапно становится нулевой.
Я не могу просто запустить изоляцию в своем приложении и отправить ему сообщение из моего обратного вызова, например, как это сделано здесь . Потому что мне нужен этот код для работы, когда приложение закрыто, а изолятор в области приложения не работает в фоновом режиме.
Итак, как я могу открыть свое приложение из обратного вызова?
Это - это полная трассировка стека
E/flutter (26735): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(error, Attempt to invoke virtual method 'android.content.pm.PackageManager android.app.Activity.getPackageManager()' on a null object reference, null)
E/flutter (26735): #0 StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:569
E/flutter (26735): #1 MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:156
E/flutter (26735): <asynchronous suspension>
E/flutter (26735): #2 MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:329
E/flutter (26735): #3 DeviceApps.openApp
package:device_apps/device_apps.dart:81
E/flutter (26735): #4 SystemOverlayController.systemOverlayOnClickListner
package:appname/…/singletons/system_overlay_controller.dart:51
E/flutter (26735): #5 callbackDispatcher.<anonymous closure>
package:system_alert_window/system_alert_window.dart:136
E/flutter (26735): #6 MethodChannel._handleAsMethodCall
package:flutter/…/services/platform_channel.dart:409
E/flutter (26735): #7 MethodChannel.setMethodCallHandler.<anonymous closure>
package:flutter/…/services/platform_channel.dart:377
E/flutter (26735): #8 _DefaultBinaryMessenger.handlePlatformMessage
package:flutter/…/services/binding.dart:199
E/flutter (26735): #9 _invoke3.<anonymous closure> (dart:ui/hooks.dart:290:15)
E/flutter (26735): #10 _rootRun (dart:async/zone.dart:1184:13)
E/flutter (26735): #11 _CustomZone.run (dart:async/zone.dart:1077:19)
E/flutter (26735): #12 _CustomZone.runGuarded (dart:async/zone.dart:979:7)
E/flutter (26735): #13 _invoke3 (dart:ui/hooks.dart:289:10)
E/flutter (26735): #14 _dispatchPlatformMessage (dart:ui/hooks.dart:164:5
Пример репозитория
Я даже пытался добавить метод открытого приложения непосредственно в разветвленную версию окно системного предупреждения. И реализовал это в примере репозитория, который вы можете найти здесь, возьмите ветку с именем my-branch.
https://github.com/michael-ottink/system_overlay_callback_null_activity
Но это выдает точно такую же ошибку. Даже если я использую точно такое же действие. Думаю, это как-то связано с фоновым каналом.
Запустите приложение и нажмите кнопку, чтобы получить оверлей. Переведите приложение в фоновый режим и нажмите «Открыть» в оверлее. Возникает ошибка.
Дополнительная информация
Я думаю, что это - аналогичная проблема, только здесь они решили не регистрировать плагин, потому что он находится на переднем плане только. Если в моем случае я хочу форкнуть любой из этих плагинов и изменить их, чтобы он также работал в фоновом режиме. Как мне это сделать?