Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/210.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Firebase可扩展通知在应用程序处于后台时显示图像_Android_Background_Push Notification_Firebase Cloud Messaging - Fatal编程技术网

Android Firebase可扩展通知在应用程序处于后台时显示图像

Android Firebase可扩展通知在应用程序处于后台时显示图像,android,background,push-notification,firebase-cloud-messaging,Android,Background,Push Notification,Firebase Cloud Messaging,我在Android中实现FCM通知,但根据应用程序状态(后台和前台),通知有何区别 我使用带有邮递员的FCM API发送通知,这是通知结构: { "notification": { "title": "Notification title", "body": "Notification message", "sound": "default", "color": "#53c4bc", "click_action": "MY_BOOK"

我在Android中实现FCM通知,但根据应用程序状态(后台和前台),通知有何区别

我使用带有邮递员的FCM API发送通知,这是通知结构:

{ "notification": {
      "title": "Notification title",
      "body": "Notification message",
      "sound": "default",
      "color": "#53c4bc",
      "click_action": "MY_BOOK",
      "icon": "ic_launcher"
   },
   "data": {
       "main_picture": "URL_OF_THE_IMAGE"  
   },
   "to" : "USER_FCM_TOKEN"
}
要渲染的图像取自
data.main\u picture

我已经实现了我自己的
FirebaseMessagingService
,它可以使通知在前台状态下完美显示。通知代码是下一个:

NotificationCompat.BigPictureStyle notiStyle = new NotificationCompat.BigPictureStyle();
notiStyle.setSummaryText(messageBody);
notiStyle.bigPicture(picture);

Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setLargeIcon(bigIcon)
            .setContentTitle(title)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)
            .setStyle(notiStyle); code here

NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
然而,在后台,甚至不执行服务。在
AndroidManifest.xml
中,Firebase服务声明如下:

<service
    android:name=".MyFirebaseMessagingService">
  <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT"/>
  </intent-filter>
</service>

<service
    android:name=".MyFirebaseInstanceIDService">
  <intent-filter>
    <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
  </intent-filter>
</service>

我的问题不是
大图标
小图标
,而是显示大图


感谢您的支持。

FCM
通知消息
不支持largeIcon或bigPicture

如果您在后台需要它们,可以使用FCM
数据消息

对于数据消息,始终调用
onMessageReceived(message)
方法,因此您可以使用
message.getData()方法创建自定义通知

在此处阅读有关通知消息与数据消息的更多信息:

如果您希望应用程序的系统托盘中只有一个通知,则以下解决方案可以解决此问题,直到FCM提出正确的解决方案

  • 从清单中删除MyFirebaseMessagingService

    <service android:name=".MyFirebaseMessagingService">   <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/>   </intent-filter> </service>
    
    
    
  • MyGcmReceiver扩展GcmReceiver类并更正通知逻辑
  • 在清单中添加MyGcmReceiver

        <receiver
        android:name=".MyGcmReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="package_name" />
        </intent-filter>
    </receiver>
    
    
    
  • 在通知通知之前取消所有通知。(否则firebase也会在应用程序处于后台时显示通知)


  • 请参阅myFirebaseMessagingService

    public class MyFirebaseMessagingService extends FirebaseMessagingService {
    
        private static final String TAG = "FirebaseMessageService";
        Bitmap bitmap;
    
        /**
         * Called when message is received.
         *
         * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
         */
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            // There are two types of messages data messages and notification messages. Data messages are handled
            // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
            // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
            // is in the foreground. When the app is in the background an automatically generated notification is displayed.
            // When the user taps on the notification they are returned to the app. Messages containing both notification
            // and data payloads are treated as notification messages. The Firebase console always sends notification
            // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
            //
            Log.d(TAG, "From: " + remoteMessage.getFrom());
    
            // Check if message contains a data payload.
            if (remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            }
    
            // Check if message contains a notification payload.
            if (remoteMessage.getNotification() != null) {
                Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
            }
    
            //The message which i send will have keys named [message, image, AnotherActivity] and corresponding values.
            //You can change as per the requirement.
    
            //message will contain the Push Message
            String message = remoteMessage.getData().get("message");
            //imageUri will contain URL of the image to be displayed with Notification
            String imageUri = remoteMessage.getData().get("image");
            //If the key AnotherActivity has  value as True then when the user taps on notification, in the app AnotherActivity will be opened. 
            //If the key AnotherActivity has  value as False then when the user taps on notification, in the app MainActivity will be opened. 
            String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");
    
            //To get a Bitmap image from the URL received
            bitmap = getBitmapfromUrl(imageUri);
    
            sendNotification(message, bitmap, TrueOrFlase);
    
        }
    
    
        /**
         * Create and show a simple notification containing the received FCM message.
         */
    
        private void sendNotification(String messageBody, Bitmap image, String TrueOrFalse) {
            Intent intent = new Intent(this, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.putExtra("AnotherActivity", TrueOrFalse);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                    PendingIntent.FLAG_ONE_SHOT);
    
            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setLargeIcon(image)/*Notification icon image*/
                    .setSmallIcon(R.drawable.firebase_icon)
                    .setContentTitle(messageBody)
                    .setStyle(new NotificationCompat.BigPictureStyle()
                            .bigPicture(image))/*Notification with Image*/
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);
    
            NotificationManager notificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
            notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
        }
    
        /*
        *To get a Bitmap image from the URL received
        * */
        public Bitmap getBitmapfromUrl(String imageUrl) {
            try {
                URL url = new URL(imageUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                Bitmap bitmap = BitmapFactory.decodeStream(input);
                return bitmap;
    
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
    
            }
        }
    }
    

    您可以使用此rest客户端工具发送消息。使用此工具,您也可以在后台和前台向客户端应用程序发送消息。 要使用API发送消息,您可以使用名为AdvancedREST客户端的工具(它是一个chrome扩展)并发送带有以下参数的消息

    Rest客户端工具链接:

    使用此url:-Content-Type:application/json-Authorization:key=您的服务器密钥来自或授权密钥(请参见下文参考)

    {“数据”:{“图像”:“消息”:“Firebase使用API推送消息”“其他活动”:“True”},“到”:“设备id或设备令牌”}

    通过访问Google开发者控制台并单击项目左侧菜单上的Credentials按钮,可以获得授权密钥。在列出的API密钥中,服务器密钥将是您的授权密钥

    您需要将接收方的tokenID放在使用API发送的POST请求的“to”部分

    这段安卓代码 //消息将包含推送消息

        String message = remoteMessage.getData().get("message1");
    
        //imageUri will contain URL of the image to be displayed with Notification
    
    
        String imageUri = remoteMessage.getData().get("image");
    
        //If the key AnotherActivity has  value as True then when the user taps on notification, in the app AnotherActivity will be opened.
    
        //If the key AnotherActivity has  value as False then when the user taps on notification, in the app MainActivity2 will be opened.
    
        String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");
    
        //To get a Bitmap image from the URL received
    
        bitmap = getBitmapfromUrl(imageUri);
    
    
        sendNotification(message, bitmap, TrueOrFlase);
    

    如果您的问题与显示大图像有关,即如果您从firebase控制台发送带有图像的推送通知,并且仅当应用程序位于前台时,才会显示图像。这个问题的解决方案是发送一个只包含数据字段的推送消息

    { "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }
    

    这无疑解决了问题。

    从Firebase控制台发送大画面通知: 适用于后台和前台应用程序

    代替
    onMessageReceived
    ,重写
    FirebaseMessagingService
    zzm()
    ,并从此处创建自定义通知

    @Override
    public void zzm(Intent intent) {
        Log.e(TAG, "zzm : " + intent);
        createBigPictureNotification();        
    }
    
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
    
    }
    

    “数据”键需要存在于推送通知包中

    除了以上的答案之外,, 如果您正在使用FCM控制台测试推送通知,则“数据”键和对象不会添加到推送通知包中。所以,当应用程序处于后台或被终止时,您将不会收到详细的推送通知

    在这种情况下,您必须选择后端管理控制台来测试应用程序后台场景

    在这里,您将向推包添加“数据”键。因此,详细的推送将按预期显示。
    希望这对您的帮助不大。

    包含通知和数据有效负载(如您与邮递员一起发送的示例)的消息将由FCM库自动显示给最终用户设备。这不包括(大)图像

    我想你有两种可能:

  • 试试Rashmi Jain的建议。但是,如果Firebase库被更新(从而消息处理的实现),该解决方案可以立即工作,明天停止工作

  • 与邮递员一起发送数据消息。因此,您可能无法在JSON中填充通知对象,因此它可能看起来像这样:

    {
      "message": {
        "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
        "data":{    
          "title" : "Awesome title",
          "body"  : "Your awesome push notification body",
          "image"  : "your_image_url"
        }
      }
    }
    

  • 我更喜欢第二种选择。祝你好运

    例如,如果要发送推送通知,则在数据中获取所有必需的内容,而不是通知

    {
       "data": {
           "main_picture": "URL_OF_THE_IMAGE",
           "title": "Notification title",
          "click_action": "MY_BOOK", 
          "color": "#53c4bc", 
       },
       "to" : "USER_FCM_TOKEN"
    }
    
    删除通知对象并从数据对象获取所有值


    希望它对您有用。

    如果2019年这里有一些土地,您只需在通知对象中添加一个图像字段即可:

        {
            notification: {
                title: title,
                body: body,
                image: "http://path_to_image"
            },
            data: {
                click_action: "FLUTTER_NOTIFICATION_CLICK",
                your_data: ...,
            },
            token: token
        }
    
    我已经在Android上使用Flatter对它进行了测试,我认为它可以在原生Android上运行,因为它们可能都使用相同的原生SDK。

    更新2019年8月

    [因为py不支持通知的最新更改而浪费了几天]

    只需将image=url添加到通知对象中即可

    它在本机Android中工作。只需将
    图像
    添加到通知对象中即可。另外请注意,Python库中不存在图像字段。[截至8月19日]

    我使用了PHP和这个库 它超级简单,更重要的是,当应用程序在后台或被杀死时,它可以用于大图像通知

    代码:


    推送5完全取决于接收到的推送请求,以及设备功能,如某些设备的电池saber会影响所有功能
    <?php
    
    require __DIR__.'/vendor/autoload.php';
    require __DIR__.'/simple_html_dom.php';
    
    use Kreait\Firebase;
    use Kreait\Firebase\ServiceAccount;
    use Kreait\Firebase\Messaging\Notification;
    use Kreait\Firebase\Messaging\CloudMessage;
    
    $serviceAccount = ServiceAccount::fromJsonFile('/path/to/cred.json');
    
    $firebase = (new Firebase\Factory())->withServiceAccount($serviceAccount)->create();
    $messaging = $firebase->getMessaging();
    
    // this works when app is closed or in bg
    $notification = Notification::fromArray([
        'title' => $title,
        'body' => $body,
        'image' => $imageUrl,
    ]);
    
    // for foreground process 
    $data = [
        'image' => $imageUrl,
        'news_id' => $news_id,
    ];
    
    $topic = 'default_topic1';
    
    $message = CloudMessage::withTarget('topic', $topic)
        ->withNotification($notification) // optional
        ->withData($data);
    
    $messaging->send($message);
    
    print_r($message);