FCM簡(jiǎn)介
1. FCM是Google的GCM升級(jí)版的一種消息推送框架(官方網(wǎng)站)
2. FCM可以在官方網(wǎng)站的控制臺(tái)Firebase console上發(fā)送通知肄梨,但是GCM不能(需要在官方網(wǎng)站添加上你的應(yīng)用才可以登陸到控制臺(tái))
FCM使用前提
- 設(shè)備必須是android4.0以上,Google Play Services 必須是 11.2.0以上版本
- Android SDK Manager 必須有Google Play services SDK
- Android Studio必須是1.5以上版本
FCM接入
-
下載google-services.json文件念祭,并將文件放置在app目錄下
說(shuō)明:如果要在不同buildType或者productFlavors下區(qū)分不同的json文件,請(qǐng)建立對(duì)應(yīng)的文件夾湾盗,并將json文件copy至對(duì)應(yīng)文件夾的根目錄下
不同的buildType時(shí)
// dogfood and release are build types.
app/
google-services.json
src/dogfood/google-services.json
src/release/google-services.json
...
不同的productFlavors時(shí)
// free and paid are product flavors.
app/
google-services.json
src/dogfood/paid/google-services.json
src/release/free/google-services.json
...
-
加入FCM需要的插件和依賴
- 在工程級(jí)別(Project-level)的build.gradle中加入:
buildscript {
repositories {
jcenter()
google() // 必填項(xiàng)(gradle plugin 3.x以上)
或者
maven { url 'https://maven.google.com' } // 必填項(xiàng)
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.0' // gradle pulagin 版本
classpath 'com.google.gms:google-services:3.1.0' // service 插件的版本(最新參考官網(wǎng))
}
}
allprojects {
repositories {
jcenter()
google() // 必填項(xiàng)(gradle plugin 3.x以上)
或者
maven { url 'https://maven.google.com' } // 必填項(xiàng)
}
}
- 在項(xiàng)目級(jí)別(Model-level)的build-gradle中加入:
apply plugin: 'com.android.application'
android {
...
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
...
implementation 'com.google.firebase:firebase-messaging:12.0.1' // FCM推送使用的依賴
}
apply plugin: 'com.google.gms.google-services'
// 必須要放在最后你辣,不然會(huì)報(bào)錯(cuò):Please fix the version conflict either by updating the version of the google-services plugin (information about the latest version is available at https://bintray.com/android/android-tools/com.google.gms.google-services/) or updating the version of com.google.android.gms to X.X.X.
如果引用了Google其他服務(wù),比如google地圖拦盹,那么需要版本一致
//下方的firebase-messaging 和 play-services-maps 和 play-services版本號(hào)必須一致
compile 'com.google.firebase:firebase-messaging:11.2.0'
compile 'com.google.android.gms:play-services-maps:11.2.0'
compile 'com.google.android.gms:play-services:11.2.0'
compile 'com.google.gms:google-services:3.1.0'
-
添加FCM相關(guān)的服務(wù)
- 創(chuàng)建FCMMessagingService,繼承FirebaseMessagingService
public class FCMMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getNotification() != null && remoteMessage.getNotification().getBody() != null) {
sendNotification(getApplicationContext(), remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
} else {
sendNotification(getApplicationContext(), remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
}
}
@Override
public void onDeletedMessages() {
super.onDeletedMessages();
}
@Override
public void onMessageSent(String s) {
super.onMessageSent(s);
}
@Override
public void onSendError(String s, Exception e) {
super.onSendError(s, e);
}
private void sendNotification(Context iContext, String messageTitle, String messageBody) {
NotificationManager notificationManager = (NotificationManager) iContext.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, MessageActivity.class); // 接收到通知后鹃祖,點(diǎn)擊通知,啟動(dòng) MessageActivity
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long[] pattern = {500,500,500,500,500};
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(),"-1")
.setTicker(messageTitle)
.setSmallIcon(R.drawable.ic_stat_notify)
.setContentTitle("push 通知 標(biāo)題")
.setAutoCancel(true)
.setContentText(messageBody)
.setWhen(System.currentTimeMillis())
.setVibrate(pattern)
.setLights(Color.BLUE, 1, 1)
builder.setDefaults(NotificationCompat.DEFAULT_SOUND | NotificationCompat.DEFAULT_VIBRATE);
builder.setContentIntent(pendingIntent);
// builder.setFullScreenIntent(pendingIntent, true);//將一個(gè)Notification變成懸掛式Notification
if (notificationManager != null) {
notificationManager.notify(0, builder.build());
}
}
}
-
創(chuàng)建FCMInstanceIDService,繼承FirebaseInstanceIdService普舆,參考官網(wǎng)
唯一Token的獲取和上傳
最初啟動(dòng)您的應(yīng)用時(shí)恬口,F(xiàn)CM SDK 會(huì)為客戶端應(yīng)用實(shí)例生成一個(gè)注冊(cè)令牌。如果您希望定位單臺(tái)設(shè)備或創(chuàng)建設(shè)備組沼侣,則需要通過(guò)繼承 FirebaseInstanceIdService
來(lái)訪問(wèn)此令牌祖能。
當(dāng)您需要檢索當(dāng)前令牌時(shí),請(qǐng)調(diào)用 FirebaseInstanceId.getInstance().getToken()
如果令牌尚未生成华临,此方法將返回 null芯杀。
public class FCMInstanceIDService extends FirebaseInstanceIdService {
@Override
public void onTokenRefresh() {
super.onTokenRefresh();
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.v("FCM----", refreshedToken);
sendRefreshToken(refreshedToken);
}
public void sendRefreshTokenToService(String refreshedToken){
//這里是往自己app應(yīng)用的后臺(tái)發(fā)送刷新refreshedToken的api
}
}
Firebase建議我們復(fù)寫onTokenRefresh方法并且及時(shí)上傳更新的Token通知App服務(wù)器
-
注冊(cè)Service
<service android:name=".FCMInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".FCMMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_notify" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
-
需要注意的問(wèn)題
-
FCM有兩種消息
1.1 顯示消息:僅當(dāng)應(yīng)用處于前臺(tái)時(shí),消息才會(huì)觸發(fā) onMessageReceived() 回調(diào)
1.2 數(shù)據(jù)消息:程序后臺(tái)運(yùn)行時(shí)接收到通知雅潭,不會(huì)走FirebaseMessagingService的 onMessageReceived() 方法揭厚,而是顯示在系統(tǒng)托盤中,此時(shí)點(diǎn)擊通知扶供,會(huì)打開App中的默認(rèn)啟動(dòng)Activity筛圆,并將數(shù)據(jù)放在Intent的extras中傳送。
所以如果app處于后臺(tái)或者被killed椿浓,想要點(diǎn)擊通知顯示MessageActivity太援,可以這樣做:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (getIntent().getExtras() != null) {
for (String s : getIntent().getExtras().keySet()) {
Log.d("MainActivity", s + "--" + getIntent().getExtras().get(s));
// 在官網(wǎng)的發(fā)送notification 使用高級(jí)選項(xiàng)可以自定義 鍵值對(duì),最終會(huì)在getIntent().getExtras()中獲取到
}
Intent intent = new Intent(this, MessageActivity.class);
startActivity(intent);
}
}
}
使用FCM云消息推送
目標(biāo)分為三種:
- 用戶細(xì)分--->對(duì)所有安裝過(guò)程序的client端進(jìn)行發(fā)送推送
- 主 題--->官方鏈接
- 單個(gè)設(shè)備--->對(duì)指定的Client進(jìn)行發(fā)送扳碍,需要一個(gè)FCM注冊(cè)令牌提岔,程序運(yùn)行起來(lái)時(shí),通過(guò)FirebaseInstanceId.getInstance().getToken()獲得笋敞,設(shè)置進(jìn)去即可