当 Firebase 通知被点击时显示特定的活动界面

5
当用户点击来自Firebase控制台的通知时,我需要在用户点击通知时启动特定的Android活动。在以下两种情况下如何实现此目标:
  1. 应用程序未打开或在后台运行
  2. 应用程序在前台运行

- 当应用程序未打开或在后台运行时,可以使用PendingIntent来启动指定的Activity。当用户点击通知时,系统会将PendingIntent发送给操作系统,并启动Activity。 - 当应用程序在前台运行时,可以使用BroadcastReceiver接收通知并执行相应的操作,例如使用AlertDialog或另一个Activity来提醒用户进行某些操作。

1
目前还没有办法控制通知被点击时启动哪个活动。请参见https://dev59.com/71oU5IYBdhLWcg3wV1-8 - Frank van Puffelen
嗨,弗兰克,你能告诉我如何从Firebase以JSON格式发送消息/通知吗? - Anuroop Kakkirala
1
您需要从服务器发送下行消息。请参阅https://firebase.google.com/docs/cloud-messaging/downstream - Frank van Puffelen
@FrankvanPuffelen 感谢您的及时回复。我该如何发送带有数据(json)的下行消息,无论是从Firebase控制台还是从任何第三方云推送平台,因为我没有访问任何内部服务器的权限? - Anuroop Kakkirala
在Firebase composer的高级部分,您可以添加键值对作为意图附加项传递给启动的活动。 - Arthur Thompson
1个回答

4
你可以通过两种方式实现这一点,
1. 第一种方法
在通知负载中添加click_action, jNotification.put("click_action", "OPEN_ACTIVITY_1");
private void pushNotification(String token) {
        JSONObject jPayload = new JSONObject();
        JSONObject jNotification = new JSONObject();
        JSONObject jData = new JSONObject();
        try {
            jNotification.put("title", "Google I/O 2016");
            jNotification.put("text", "Firebase Cloud Messaging (App)");
            jNotification.put("sound", "default");
            jNotification.put("badge", "1");
            jNotification.put("click_action", "OPEN_ACTIVITY_1");

            jData.put("picture_url", "http://opsbug.com/static/google-io.jpg");

            jPayload.put("to", token);
            //jPayload.put("to", "/topics/news");
            //jPayload.put("condition", "'logined' in topics || 'news' in topics");
            //jPayload.put("registration_ids", jData);
            jPayload.put("priority", "high");
            jPayload.put("notification", jNotification);
            jPayload.put("data", jData);

            URL url = new URL("https://fcm.googleapis.com/fcm/send");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Authorization", AUTH_KEY);
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoOutput(true);

            // Send FCM message content.
            OutputStream outputStream = conn.getOutputStream();
            outputStream.write(jPayload.toString().getBytes());

            // Read FCM response.
            InputStream inputStream = conn.getInputStream();
            final String resp = convertStreamToString(inputStream);

            Handler h = new Handler(Looper.getMainLooper());
            h.post(new Runnable() {
                @Override
                public void run() {
                    Log.e("Response", resp);
                    //txtStatus.setText(resp);
                }
            });
        } catch (JSONException | IOException e) {
            e.printStackTrace();
        }
    }

请将以下代码添加到 AndroidManifest.xml 文件中:
        <activity android:name="com.example.fcm.SecondActivity">
            <intent-filter>
                <action android:name="OPEN_ACTIVITY_1" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

MyFirebaseMessagingService.java

  public class MyFirebaseMessagingService extends FirebaseMessagingService {
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            super.onMessageReceived(remoteMessage);

            // If the application is in the foreground handle both data and notification messages here.
            // Also if you intend on generating your own notifications as a result of a received FCM
            // message, here is where that should be initiated. See sendNotification method below.

            RemoteMessage.Notification notification = remoteMessage.getNotification();
            Map<String, String> map = remoteMessage.getData();

            sendNotification(notification.getTitle(), notification.getBody(), map);
        }

        private void sendNotification(String title, String body, Map<String, String> map) {
            Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

            Intent intent = new Intent(this, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);

            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setContentTitle(title)
                    .setContentText(body)
                    .setAutoCancel(true)
                    .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                    .setContentIntent(pendingIntent)
                    .setContentInfo(title)
                    .setLargeIcon(icon)
                    .setSmallIcon(R.mipmap.ic_launcher);

            try {
                String picture_url = map.get("picture_url");
                if (picture_url != null && !"".equals(picture_url)) {
                    URL url = new URL(picture_url);
                    Bitmap bigPicture = BitmapFactory.decodeStream(url.openConnection().getInputStream());
                    notificationBuilder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bigPicture).setSummaryText(body));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
            notificationBuilder.setLights(Color.YELLOW, 1000, 300);

            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(0, notificationBuilder.build());
        }
    }

SecondActivity.java

public class SecondActivity extends AppCompatActivity {
    private static final String TAG = "SecondActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        Bundle bundle = getIntent().getExtras();

        if (bundle != null) {
            for (String key : bundle.keySet()) {
                Object value = bundle.get(key);
                Log.d(TAG, "Key: " + key + " Value: " + value.toString());
            }
        }
    }
}

2. 第二种方法

通过数据负载(data payload)发送密钥,如下所示,在MainActivity中通过getIntent()获取密钥并调用特定的活动或片段。

        json1.put("title","Your Title");  
        json1.put("body","body content");  
        json1.put("message","Your Message");  
        json1.put("screen","2");   //secondFragment is 2nd position in nav drawer
        json.put("data", json1); 

MainActivity.java

Intent intent = getIntent();
        String pos = getIntent().getStringExtra("screen");
        if(pos !=null){
            selectDrawerItem(navigationView.getMenu().getItem(Integer.parseInt(pos)));
        }

GITHUB上的示例项目, https://github.com/Google-IO-extended-bangkok/FCM-Android


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接