Flutter 中的 AndroidManifest 中缺少默认通知通道元数据

Posted

技术标签:

【中文标题】Flutter 中的 AndroidManifest 中缺少默认通知通道元数据【英文标题】:Missing default Notification Channel metadata in AndroidManifest in Flutter 【发布时间】:2019-10-19 01:58:49 【问题描述】:

我正在使用firebase_messaging: ^5.0.1 包来实现推送通知,在 ios 中一切正常,而当我的移动应用程序在后台运行时进入 android 我收到通知但它没有导航到相应的屏幕,它只是打开默认屏幕。如何实现到特定屏幕的导航。

PS:我实现了 click_action 功能,这就是它在 iOS 中运行良好但在 Android 中显示以下消息的原因

W/FirebaseMessaging( 8260): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.

这是我的 AndroidManifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.check">

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="Cargill FC"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:allowBackup="false"
            android:fullBackupContent="false"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

推送通知码:

@override
  void initState() 
    super.initState();
    tabController = new TabController(length: 2, vsync: this);

    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async 
        onFirebaseMessage(message);
      ,
      onLaunch: (Map<String, dynamic> message) async 
        print("onLaunch: $message");
      ,
      onResume: (Map<String, dynamic> message) async 
        print("onResume: $message");
      ,
    );

    _firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings(sound: true, badge: true, alert: true));
    _firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) 
      print("Settings registered: $settings");
    );

    _firebaseMessaging.getToken().then(registerFirebaseTokenForUser);
  

这里的 onMessage 是唯一能在 Android 中完美运行的东西。我想在后台运行时达到同样的效果。

【问题讨论】:

嘿,我也有同样的问题,你解决了吗?尝试了 Maksim 的答案,但仍然无法正常工作 Harsha,请将答案标记为正确或提供您自己的答案! 是的,firebase 的响应告诉我应该有一个 click_action 作为 FLUTTER_NOTIFICATION_CLICK。 【参考方案1】:

找不到“string.xml”的可以在android>app>src>main>res>下找到值。它与 styles.xml 不同。如果您还没有,您可以创建一个:

    右击“values”文件夹, 单击新建/值资源文件 复制并粘贴以下文本:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
</resources>

【讨论】:

【参考方案2】:

Maksim 在这里有一个非常可靠的答案,包括官方文档的链接。您需要在 Manifest 中添加以下元数据标签:

<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/default_notification_channel_id"/>

string.xml 中,您可以通过以下方式声明 default_notification_channel_id: &lt;string name=“default_notification_channel_id”&gt;Channel ID&lt;/string&gt;

那么您必须在发送推送通知时提供具有该特定 id 的属性。

编辑 AndroidManifest.xml 中可以有多个元数据标签:

            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <meta-data
                android:name="com.google.firebase.messaging.default_notification_channel_id"
                android:value="@string/default_notification_channel_id"/>

【讨论】:

但是先生,我在元数据&lt;meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:value="true" /&gt; 中指定了一些内容,如果我在元数据中添加它会引发错误,对吗?? 我试过@Maksim 回答它对我不起作用,这就是我发布一个新问题的原因。 抱歉,过了这么久才回复您。我更新了我的帖子以包含一个如何在清单中包含多个 &lt;meta-data/&gt; 标记的示例。让我知道结果如何。另一方面,最好在发布问题时指出您尝试过的解决方案:) * What went wrong: Execution failed for task ':app:processDebugResources'. &gt; Android resource linking failed Output: /Users/xxx/Workspace/xxx/build/app/intermediates/merged_manifests/debug/processDebugManifest/merged/AndroidManifest.xml:53: error: resource string/default_notification_channel_id (aka com.iotrl.cargill_fc:string/default_notification_channel_id) not found. error: failed processing manifest.这是我得到的,我在flutter项目中找不到String.xml @HarshaVardhan 你应该在某处定义了 id default_notification_channel_id 的字符串.. :O【参考方案3】:

添加要发送的FLUTTER_NOTIFICATION_CLICK is required,以便执行onResume 和onLunch。

 
    "notification": ...,
    "click_action": "FLUTTER_NOTIFICATION_CLICK"
 

对于我的 golang 服务器,这意味着添加 AndroidConfig

message := &messaging.Message
    Topic: topic,
    Notification: &messaging.Notification/* */
    Data: data,
    APNS: &messaging.APNSConfig/* */
    Android: &messaging.AndroidConfig
        Notification: &messaging.AndroidNotification
            ClickAction: "FLUTTER_NOTIFICATION_CLICK",
        ,
    ,

【讨论】:

【参考方案4】:

1- 首先,在位于路径&lt;flutter project path&gt;/android/app/src/main/AndroidManifest.xmlAndroidManifest.xml 中的&lt;/activity&gt; 标记之后添加此元代码

<meta-data
   android:name="com.google.firebase.messaging.default_notification_channel_id"
   android:value="@string/notification_channel_id" />

注意:如果您在&lt;activity&gt; 中设置此元数据,代码将不起作用。

2- 修改此路径&lt;flutter project path&gt;/android/app/src/main/res/values/string.xml 中的文件(如果不存在则创建新文件)如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
</resources>

这样就可以解决问题Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.

但之后,您需要在 Android 中创建此频道,然后转到文件 &lt;flutter project path&gt;//android/app/src/main/kotlin/com/examble/project_name/Application.kt 并添加此功能:

private fun createChannel()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
        // Create the NotificationChannel
        val name = getString(R.string.default_notification_channel_id)
        val channel = NotificationChannel(name, "default", NotificationManager.IMPORTANCE_HIGH)
        val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    

然后从onCreate()函数调用它:

override fun onCreate() 
    super.onCreate()
    createChannel()
    .........

【讨论】:

【参考方案5】:

在我的通知数据中添加 'click_action': 'FLUTTER_NOTIFICATION_CLICK' 为我解决了这个问题

【讨论】:

【参考方案6】:

如果您的颤振版本大于1.12,您不需要创建任何文件,如Application.javaApplication.kt,只需将以下元值添加到您的AndroidManifest 文件中

<meta-data
     android:name="com.google.firebase.messaging.default_notification_channel_id"
       android:value="high_importance_channel" />

参考:https://firebase.flutter.dev/docs/messaging/overview/

【讨论】:

以上是关于Flutter 中的 AndroidManifest 中缺少默认通知通道元数据的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Flutter 中的 Form 需要 GlobalKey?

将 'tools:replace="Android:value"' 添加到 AndroidManifest 中的 <meta-data> 元素

如何去除 Flutter 中的“XMLHttpRequest 错误”? (Django 后端,Flutter 前端)

Firebase 权限被拒绝错误

Flutter 中的 pushReplacementNamed 和 popAndPushNamed 有啥区别?

Flutter 中的 shrinkWrap 属性有啥作用?