首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Flutter:在应用程序关闭或处于后台时运行本机android代码

Flutter:在应用程序关闭或处于后台时运行本机android代码
EN

Stack Overflow用户
提问于 2021-09-30 11:52:40
回答 2查看 836关注 0票数 0

我使用Firebase和颤振本地通知来显示从我的服务器获得的通知。我希望在android通知的会话部分中显示某些通知,因此我使用方法通道进行了本机kotlin调用,以便为此创建一个快捷方式:

Dart

代码语言:javascript
复制
  static Future<String?> _createConversationShortcut(
      String personName, String personIconPath) async {
    const platform = MethodChannel('...');
    String result;
    try {
      result = await platform.invokeMethod('createConversationShortcut', {
        'personName': personName,
        'personIcon': personIconPath,
      });
    } on PlatformException catch (e) {
      return null;
    }
    return result;
  }

我调用方法_createConversationShortcut本地创建快捷方式,然后在AndroidNotificationDetails中使用快捷ID,以便通知位于会话部分。

代码语言:javascript
复制
      flutterLocalNotificationsPlugin.show(
        int.parse(person.key!),
        notification,
        text,
        NotificationDetails(
          android: AndroidNotificationDetails(
            channel.id,
            channel.name,
            channel.description,
            icon: '@drawable/is_notification',
            category: 'msg',
            shortcutId: shortcutId,
            styleInformation: MessagingStyleInformation(
              person,
              groupConversation: false,
              conversationTitle: 'Neue Privatnachricht',
              messages: messages,
            ),
            //setAsGroupSummary: true,
          ),
        ),
        payload: json.encode(payload),
      );

Kotlin

代码语言:javascript
复制
class MainActivity: FlutterActivity() {

    private val CHANNEL = "..."

    private fun createConversationShortcut(personName: String, personIcon: String): String {
        val person = Person.Builder()
                .setName(personName)
                .setIcon(IconCompat.createWithContentUri(personIcon))
                .build()
        val shortcut = ShortcutInfoCompat.Builder(context, personName.toLowerCase(Locale.ROOT).replace(" ", "_") + "_shortcut")
                .setLongLived()
                .setIntent(Intent(Intent.ACTION_VIEW))
                .setPerson(person)
                .setShortLabel(personName)
                .build()
        ShortcutManagerCompat.addDynamicShortcuts(context, listOf(shortcut))
        return shortcut.id
    }

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "createConversationShortcut") {
                val personName = call.argument<String>("personName")
                val personIcon = call.argument<String>("personIcon")
                if (personName != null && personIcon != null) {
                    val shortcutId = createConversationShortcut(personName, personIcon)
                    result.success(shortcutId)
                } else {
                    result.error("argument-error", "Too few arguments", null)
                }
            } else {
                result.notImplemented()
            }
        }
    }
}

当应用程序位于前台时,这个功能非常好,但是当我的应用程序处于后台或关闭时,我会得到一个ImplementationError,因为MainActivity不存在。

我现在的问题是,当应用程序处于后台或关闭时,我如何调用方法通道?我读到需要为此创建一个服务,但我不知道如何从服务内部设置方法调用处理程序。有人能帮我吗?

编辑:

在应用程序第一次打开后,我尝试通过在dart主文件中进行方法调用来启动服务。

代码语言:javascript
复制
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    GeneratedPluginRegistrant.registerWith(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
        if (call.method == "startHeadlessService"){
            if (!context.isMyServiceRunning(FlutterService::class.java)) {
                Log.d("pushNotificationService", "Service starting")
                val intent = Intent(context, FlutterService::class.java)
                context.startService(intent)
            } else {
                Log.d("pushNotificationService", "Service already Running")
            }
            result.success(null)
        } else {
            result.notImplemented()
        }
    }
}

在我的服务的onStartCommand函数中,我尝试设置如下方法通道:

代码语言:javascript
复制
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    Log.d("TAG", "Hello foreground service")
    FlutterMain.startInitialization(this);
    FlutterMain.ensureInitializationComplete(this, null);
    val flutterEngine = FlutterEngine(this)
    GeneratedPluginRegistrant.registerWith(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
        if (call.method == "createConversationShortcut") {
            val personName = call.argument<String>("personName")
            val personIcon = call.argument<String>("personIcon")
            if (personName != null && personIcon != null) {
                val shortcutId = createConversationShortcut(personName, personIcon)
                result.success(shortcutId)
            } else {
                result.error("argument-error", "Too few arguments", null)
            }
        }
    }
    return super.onStartCommand(intent, flags, startId)
}

但我还是发现了错误:

代码语言:javascript
复制
Unhandled Exception: MissingPluginException(No implementation found for method saveBitmapAsCircle on channel ...)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-05 09:08:12

我不知道如何在没有活动的情况下使方法通道可用,但是我发现如果创建一个插件,方法通道总是可以访问的,即使应用程序关闭了,所以我制作了一个插件,可以用来创建会话快捷方式,作为通知插件的一个补充。

如果有人感兴趣:快捷方式

票数 0
EN

Stack Overflow用户

发布于 2021-10-05 09:18:16

如果要顺利运行,请使用此包:获取

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69391772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档