版权声明:本文为博主原创文章,未经允许不得转载,如有问题,欢迎指正,谢谢! https://blog.csdn.net/cbk861110/article/details/88627497
项目源码请移步:https://github.com/caobaokang419/FirebaseApp(欢迎Github Fork&Star,如有描述错误的地方,请帮忙指正),谢谢!
一、 概念阐述:
Firebase Cloud Messaging (云消息):FCM是一种跨平台消息传递解决方案,您可以使用它免费且可靠地传递消息和通知(每条消息不能超过4KB)。
二、云消息的集成说明:
- Cloud Message(云消息) :需自备梯子
三、代码汉化说明:
1. project build.gradle 添加:
implementation 'com.google.firebase:firebase-iid:17.0.4' implementation 'com.google.firebase:firebase-messaging:17.3.4' implementation 'com.firebase:firebase-jobdispatcher:0.8.5'
2. AndroidManifest.xml 添加(Firebase后台配置云消息,应用侧负责消息处理):
<!-- APP处于前台时:可以在FCMessagingService.onMessageReceived()全权处理消息如自定义notification : large_icon , small_icon , color . APP处于后台时:由系统通知处理这部分显示,只可以在Manifest定义 : icon、color--> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_stat_ic_notification" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorAccent" /> <activity android:name=".fcm.FcmActivity" android:label="@string/fb_cloud_message_label" android:theme="@style/AppTheme" /> <service android:name=".fcm.FCMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
3. 后台Service(应用后台时,负责解析&弹出云消息通知)
public class FCMessagingService extends FirebaseMessagingService { private static final String TAG = "MyFirebaseMsgService"; /** * Called when message is received. * * @param remoteMessage Object representing the message received from Firebase Cloud Messaging. */ @Override public void onMessageReceived(RemoteMessage remoteMessage) { // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: " + remoteMessage.getFrom()); //1. 用于处理云消息 //并不是所有的消息都在这里处理,如果APP处在后台接收带数据的通知,那么数据会放在启动activity的Intent中 if ((remoteMessage.getFrom().startsWith("/topics/"))) { String topic = remoteMessage.getFrom().replace("/topics/", ""); Log.d(TAG, "From: " + remoteMessage.getFrom()); Log.d(TAG, "From: " + topic); } // 2. 检查是否包含通知 if (remoteMessage.getNotification() != null) { Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); } } /** * 3. APP发出FCM云推送过来的通知 * * @param title FCM message title received. * @param messageBody FCM message body received. */ private void sendNotification(String title, String messageBody) { Intent intent = new Intent(this, FcmActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /*Request code */, intent, PendingIntent.FLAG_ONE_SHOT); String channelId = getString(R.string.default_notification_channel_id); Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.ic_stat_ic_notification) .setContentTitle(title) .setContentText(messageBody) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // Since android Oreo notification channel is needed. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(channelId, "Channel human readable title", NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channel); } notificationManager.notify(0 /*ID of notification */, notificationBuilder.build()); } }
4. Activity实现(点击云消息通知,配置拉起此Activity,并处理云消息的data部分数据):
public class FcmActivity extends AppCompatActivity { private static final String TAG = "AnalyticsActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fb_fcm); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Create channel to show notifications. String channelId = getString(R.string.default_notification_channel_id); String channelName = getString(R.string.default_notification_channel_name); NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW)); } // 1. 当Notification的类型是message+data时,data在此处理(点击fcm通知时自动触发启动Activity时) if (getIntent().getExtras() != null) { for (String key : getIntent().getExtras().keySet()) { Object value = getIntent().getExtras().get(key); Log.d(TAG, "Key: " + key + " Value: " + value); } } //2. 应用侧上报:订阅主题:"Weather"(用于Firebase后台配置:可通过主题差异化配置云消息的运营方式) Button subscribeButton = findViewById(R.id.subscribeButton); subscribeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "Subscribing to weather topic"); FirebaseMessaging.getInstance().subscribeToTopic("weather") .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { String msg = getString(R.string.msg_subscribed); if (!task.isSuccessful()) { msg = getString(R.string.msg_subscribe_failed); } } }); } }); //3. 应用侧查询:注册的设备唯一的FCM令牌(用于Firebase后台配置:可通过令牌测试单一设备) Button logTokenButton = findViewById(R.id.logTokenButton); logTokenButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Get token FirebaseInstanceId.getInstance().getInstanceId() .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() { @Override public void onComplete(@NonNull Task<InstanceIdResult> task) { if (!task.isSuccessful()) { Log.w(TAG, "getInstanceId failed", task.getException()); return; } // 获取设备Instance ID token,用于服务端推送单一设备. String token = task.getResult().getToken(); } }); } }); } }