本來是想吐槽的戴陡,寫到最好發(fā)現(xiàn)官網(wǎng)好清晰
不容易發(fā)現(xiàn)的官方API
集成步驟:開發(fā)準(zhǔn)備官方鏈接地址
創(chuàng)建應(yīng)用梯投,添加簽名證書
- 打開命令行工具(使用CMD命令)命辖,執(zhí)行cd命令進(jìn)入
keytool.exe
所在的目錄
- 打開命令行工具(使用CMD命令)命辖,執(zhí)行cd命令進(jìn)入
- 執(zhí)行命令
keytool -list -v -keystore <keystore-file>
,按命令行提示進(jìn)行操作分蓖。<keystore-file>
為應(yīng)用簽名文件的完整路徑尔艇。填寫SHA256
,然后等十幾分鐘后下載對應(yīng)的agcibbetct0services.json
文件么鹤。
- 執(zhí)行命令
keytool -list -v -keystore I:\yhxx\releasexxxxx.keystore
添加應(yīng)用的AppGallery Connect配置文件
a. 登錄 AppGallery Connect 網(wǎng)站终娃,選擇“我的項(xiàng)目”。
b. 在項(xiàng)目列表中找到您的項(xiàng)目午磁,在項(xiàng)目中點(diǎn)擊需要集成HMS SDK的應(yīng)用尝抖。
c. 在“項(xiàng)目設(shè)置”頁面中,單擊“應(yīng)用”欄下的agconnect-services.json
下載配置文件迅皇。
d. 將agconnect-services.json
文件拷貝到應(yīng)用級根目錄下昧辽。
配置HMS SDK的maven倉地址
a. 打開AndroidStudio項(xiàng)目級project
下的build.gradle
文件。
b. 在
allprojects ->repositories
里面配置HMS SDK的maven倉地址登颓。
allprojects {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
c. 在buildscript ->repositories
里面配置HMS SDK的maven
倉地址搅荞。
buildscript {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
d. 在buildscript -> dependencies
里面增加配置。
buildscript {
dependencies {
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
}
}
添加編譯依賴
a. 打開應(yīng)用級module
的build.gradle
文件。
b. 在
dependencies
中添加如下編譯依賴咕痛。說明:
{version}
替換為實(shí)際的·SDK·版本號:implementation 'com.huawei.hms:push:4.0.3.301'
根據(jù)文檔來填寫痢甘,版本號好像更新
dependencies {
//其它已存在的依賴不要刪除 implementation 'com.huawei.hms:push:4.0.3.301
implementation 'com.huawei.hms:push:{version}'
}
c. 在應(yīng)用級build.gradle
文件尾添加配置。
apply plugin: 'com.huawei.agconnect'
配置簽名(不可少茉贡,否則會獲取不到token塞栅,6003錯誤)
android {
signingConfigs {
config {
keyAlias 'yalun'
keyPassword '123456'
storeFile file('I:/yhxx/release1.keystore')
storePassword '123456'
}
}
buildTypes {
debug {
signingConfig signingConfigs.config
}
release {
signingConfig signingConfigs.config
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
同步工程
修改完的build.gradle
文件,點(diǎn)擊右上方出現(xiàn)Sync Now
等待同步完成腔丧。
注冊HWPushReceiverService:
配置完成后放椰,可以通過兩種方式獲取token,一種是清單文件直接加入配置愉粤,可以再onNewToken方法里面直接獲取砾医,推薦。再一種是設(shè)置一下衣厘,也是在onNewToken方法中獲取token如蚜。參考本項(xiàng)目中的類HWPushReceiverService
HWPushReceiverService
類需要開發(fā)者自己定義,繼承于com.huawei.hms.push.HmsMessageService
類并實(shí)現(xiàn)其中的方法影暴。
exported
屬性需要設(shè)置為false
错邦。
package com.cc.pushallsdk;
import android.text.TextUtils;
import android.util.Log;
import com.huawei.hms.push.HmsMessageService;
import com.huawei.hms.push.RemoteMessage;
import java.util.Arrays;
public class HWPushReceiverService extends HmsMessageService {
private static String TAG=HWPushReceiverService.class.getSimpleName();
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.i(TAG, "getCollapseKey: " + remoteMessage.getCollapseKey()
+ "\n getData: " + remoteMessage.getData()
+ "\n getFrom: " + remoteMessage.getFrom()
+ "\n getTo: " + remoteMessage.getTo()
+ "\n getMessageId: " + remoteMessage.getMessageId()
+ "\n getOriginalUrgency: " + remoteMessage.getOriginalUrgency()
+ "\n getUrgency: " + remoteMessage.getUrgency()
+ "\n getSendTime: " + remoteMessage.getSentTime()
+ "\n getMessageType: " + remoteMessage.getMessageType()
+ "\n getTtl: " + remoteMessage.getTtl());
RemoteMessage.Notification notification = remoteMessage.getNotification();
if (notification != null) {
Log.i(TAG, "\n getImageUrl: " + notification.getImageUrl()
+ "\n getTitle: " + notification.getTitle()
+ "\n getTitleLocalizationKey: " + notification.getTitleLocalizationKey()
+ "\n getTitleLocalizationArgs: " + Arrays.toString(notification.getTitleLocalizationArgs())
+ "\n getBody: " + notification.getBody()
+ "\n getBodyLocalizationKey: " + notification.getBodyLocalizationKey()
+ "\n getBodyLocalizationArgs: " + Arrays.toString(notification.getBodyLocalizationArgs())
+ "\n getIcon: " + notification.getIcon()
+ "\n getSound: " + notification.getSound()
+ "\n getTag: " + notification.getTag()
+ "\n getColor: " + notification.getColor()
+ "\n getClickAction: " + notification.getClickAction()
+ "\n getChannelId: " + notification.getChannelId()
+ "\n getLink: " + notification.getLink()
+ "\n getNotifyId: " + notification.getNotifyId());
}
}
@Override
public void onDeletedMessages() {
super.onDeletedMessages();
}
/**
*
*清單文件設(shè)置了自動初始化能力的應(yīng)用,不需要顯式的調(diào)用getToken申請token坤检,
* Push SDK會自動申請token兴猩,并通過onNewToken回調(diào)方法返回。
*/
@Override
public void onNewToken(String token) {
super.onNewToken(token);
if (!TextUtils.isEmpty(token)) {
// refreshedTokenToServer(token);
}
}
@Override
public void onTokenError(Exception e) {
super.onTokenError(e);
}
}
清單文件AndroidManifest.xml
集成的所有的可能用得到的
<application>
<!--華為-->
<provider
android:name="com.huawei.agconnect.core.provider.AGConnectInitializeProvider"
android:authorities="${applicationId}.AGCInitializeProvider"
android:exported="false" />
<service
android:name="com.huawei.agconnect.core.ServiceDiscovery"
android:exported="false" />
<service
android:name="com.huawei.hms.support.api.push.service.HmsMsgService"
android:enabled="true"
android:exported="true"
android:process=":pushservice">
<intent-filter>
<action android:name="com.huawei.push.msg.NOTIFY_MSG" />
<action android:name="com.huawei.push.msg.PASSBY_MSG" />
</intent-filter>
</service>
<!-- 自定義的HWPushReceiverService extends HmsMessageService-->
<service
android:name="com.cc.pushallsdk.HWPushReceiverService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- 通知消息:點(diǎn)擊不需要程序內(nèi)容做處理早歇,需要自定義跳轉(zhuǎn)就要定義協(xié)議-->
<!-- 透傳消息:繼承HmsMessageService里面復(fù)寫onMessageReceived該方法,接收透傳參數(shù)-->
<activity android:name="com.cc.pushallsdk.TargetActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="com.cc.pushallsdk"
android:path="/wandanotify"
android:scheme="wandapushscheme" />
</intent-filter>
</activity>
</application>
配置工程project.properties
文件(不知是否必要讨勤,官方寫了反正我添加了)
打開您的工程的project.properties
文件箭跳,添加如下代碼,用于合并子工程中的Manifest
文件潭千。
manifestmerger.enabled=true
集成步驟:[基礎(chǔ)能力官方鏈接地址]
https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/push-basic-capability
基礎(chǔ)能力概覽
Step1與Step2谱姓,開發(fā)者的App集成HMS SDK,再調(diào)用HmsInstanceId.getToken接口獲取到Push Token刨晴,請參考申請Push Token章節(jié)屉来。
Step3,開發(fā)者的App將獲取到的Push Token上報到開發(fā)者服務(wù)器App Provider Server上狈癞。
Step4茄靠,開發(fā)者使用服務(wù)器保存的Push Token調(diào)用Push服務(wù)端提供的API推送Push消息,請參考服務(wù)端開發(fā)指導(dǎo)章節(jié)蝶桶。
Step5慨绳,Push服務(wù)器將開發(fā)者推送的Push消息發(fā)送給Push Token對應(yīng)的用戶設(shè)備,設(shè)備接收Push消息,請參考接收透傳消息章節(jié)脐雪。
Step6與Step7厌小,Push服務(wù)器檢測到設(shè)備回復(fù)消息響應(yīng)時,將響應(yīng)狀態(tài)回執(zhí)給開發(fā)者战秋,開發(fā)者需實(shí)現(xiàn)消息回執(zhí)接收能力璧亚,請參考服務(wù)端開發(fā)指導(dǎo)章節(jié)。
2. 客戶端開發(fā)指導(dǎo)
本章節(jié)指導(dǎo)開發(fā)者完成Push基礎(chǔ)能力開發(fā)中的客戶端開發(fā)脂信,通過本開發(fā)指導(dǎo)的學(xué)習(xí)能夠幫助開發(fā)者快速掌握客戶端開發(fā)所需的知識技能涨岁,快速體驗(yàn)華為Push服務(wù)〖基礎(chǔ)能力客戶端開發(fā)主要包括如下4個功能點(diǎn):
1梢薪、開發(fā)者集成Push SDK后申請Push Token,請參考申請Push Token章節(jié)尝哆,同時Push SDK 4.0版本我們提供了自動初始化獲取token的能力秉撇,請參考自動初始化章節(jié)
2、開發(fā)者App客戶端接收服務(wù)端推送的Push透傳消息秋泄,請參考接收透傳消息章節(jié)
3琐馆、是否允許NC(Notification Center)顯示通知欄消息,請參考設(shè)置是否顯示通知欄消息章節(jié)
4恒序、自定義點(diǎn)擊消息的動作以及向App傳遞數(shù)據(jù)可以參考點(diǎn)擊通知消息章節(jié)
1瘦麸、調(diào)用getToken方法獲取Token
private void getToken() {
new Thread() {
@Override
public void run() {
try {
// read from agconnect-services.json
String appId = AGConnectServicesConfig.fromContext(this).getString("client/app_id");
String token = HmsInstanceId.getInstance(this).getToken(appId, "HCM");
Log.i(TAG, "get token:" + token);
if(!TextUtils.isEmpty(token)) {
sendRegTokenToServer(token);
}
} catch (ApiException e) {
Log.e(TAG, "get token failed, " + e);
}
}
}.start();
}
private void sendRegTokenToServer(String token) {
Log.i(TAG, "sending token to server. token:" + token);
}
2.3 接收透傳消息
2.3.1 場景介紹
App如果訂閱了主題消息或者服務(wù)器主動推送的透傳消息(包括通知消息前臺展示功能中設(shè)置通知消息由應(yīng)用自己處理
,區(qū)別于NC (Notification Center)通知欄消息
)歧胁,都需要App通過實(shí)現(xiàn)onMessageReceived回調(diào)方法來接收消息滋饲,收到消息的后續(xù)行為由應(yīng)用自己處理
。
重寫onMessageReceived
繼承于HmsMessageService所復(fù)寫的方法獲取透傳
消息數(shù)據(jù)喊巍。
@Override
public void onMessageReceived(RemoteMessage message) {
Log.i(TAG, "onMessageReceived is called");
if (message == null) {
Log.e(TAG, "Received message entity is null!");
return;
}
Log.i(TAG, "getCollapseKey: " + message.getCollapseKey()
+ "\n getData: " + message.getData()
+ "\n getFrom: " + message.getFrom()
+ "\n getTo: " + message.getTo()
+ "\n getMessageId: " + message.getMessageId()
+ "\n getOriginalUrgency: " + message.getOriginalUrgency()
+ "\n getUrgency: " + message.getUrgency()
+ "\n getSendTime: " + message.getSentTime()
+ "\n getMessageType: " + message.getMessageType()
+ "\n getTtl: " + message.getTtl());
RemoteMessage.Notification notification = message.getNotification();
if (notification != null) {
Log.i(TAG, "\n getImageUrl: " + notification.getImageUrl()
+ "\n getTitle: " + notification.getTitle()
+ "\n getTitleLocalizationKey: " + notification.getTitleLocalizationKey()
+ "\n getTitleLocalizationArgs: " + Arrays.toString(notification.getTitleLocalizationArgs())
+ "\n getBody: " + notification.getBody()
+ "\n getBodyLocalizationKey: " + notification.getBodyLocalizationKey()
+ "\n getBodyLocalizationArgs: " + Arrays.toString(notification.getBodyLocalizationArgs())
+ "\n getIcon: " + notification.getIcon()
+ "\n getSound: " + notification.getSound()
+ "\n getTag: " + notification.getTag()
+ "\n getColor: " + notification.getColor()
+ "\n getClickAction: " + notification.getClickAction()
+ "\n getChannelId: " + notification.getChannelId()
+ "\n getLink: " + notification.getLink()
+ "\n getNotifyId: " + notification.getNotifyId());
}
Boolean judgeWhetherIn10s = false;
// If the messages are not processed in 10 seconds, the app needs to use WorkManager for processing.
if (judgeWhetherIn10s) {
startWorkManagerJob(message);
} else {
// Process message within 10s
processWithin10s(message);
}
}
private void startWorkManagerJob(RemoteMessage message) {
Log.d(TAG, "Start new job processing.");
}
private void processWithin10s(RemoteMessage message) {
Log.d(TAG, "Processing now.");
}
2.4 設(shè)置是否顯示通知欄消息
2.4.1 場景介紹
通知消息是由系統(tǒng)直接在通知中心下拉列表呈現(xiàn)的即時消息屠缭。開發(fā)者如果想控制應(yīng)用是否允許顯示通知欄消息,可以調(diào)用HmsMessaging.turnOnPush或者HmsMessaging.turnOffPush接口崭参。如果開發(fā)者不調(diào)用此接口呵曹,系統(tǒng)默認(rèn)是允許顯示通知欄消息。
HmsMessaging.getInstance(context).turnOnPush().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(Task<Void> task) {
if (task.isSuccessful()) {
Log.i(TAG, "turnOnPush Complete");
} else {
Log.e(TAG, "turnOnPush failed: ret=" + task.getException().getMessage());
}
}
});
2.5 點(diǎn)擊通知消息
關(guān)于通知消息何暮,開發(fā)者可以自定義點(diǎn)擊消息的動作奄喂,包括:打開App首頁、打開特定URL海洼、打開自定義富媒體消息跨新、打開自定義App頁面
。其中打開App首頁與自定義App頁面
需要開發(fā)者端云協(xié)同開發(fā)來完成贰军,下面我們講下如何實(shí)現(xiàn)這兩種動作并從服務(wù)端接收數(shù)據(jù)玻蝌。
注意:
1蟹肘、點(diǎn)擊動作觸發(fā)打開應(yīng)用首頁或者自定義App頁面,都是通過跨應(yīng)用啟動Activity的方式來實(shí)現(xiàn)俯树,需要保證要拉起的目標(biāo)Activity的exported屬性為true帘腹,即目標(biāo)Activity要對外界公開,并且無權(quán)限保護(hù)许饿,這樣才能啟動成功阳欲。
2、通過通知消息傳遞數(shù)據(jù)給應(yīng)用需要推送服務(wù)App版本為10.0.0及以上陋率。
2.5.1 打開自定義App頁面
打開自定義App頁面
有兩種方式球化,一種是通過服務(wù)端REST API
指定intent參數(shù),另一種是指定action參數(shù)瓦糟。如果同時指定了兩個參數(shù)筒愚,會優(yōu)先選取使用intent參數(shù)。
指定intent參數(shù)
跨應(yīng)用啟動Activity必須使用顯式intent方式菩浙,通過intent
可以攜帶額外的數(shù)據(jù)給客戶端App
1巢掺、intent參數(shù)生成
在AndroidStudio工程中參照如下代碼生成intent。
Intent intent = new Intent(Intent.ACTION_VIEW);
// Scheme協(xié)議(pushscheme://com.huawei.codelabpush/deeplink?)需要開發(fā)者自定義比如:`"wandapushscheme://com.cc.pushallsdk/wandanotify?`content=thisistest")
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
// 往intent中添加參數(shù)劲蜻,用戶可以根據(jù)自己的需求進(jìn)行添加參數(shù)
intent.putExtra("name", "abc");
intent.putExtra("age", 180);
// 必須帶上該Flag
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);
// 打印出的intentUri值就是設(shè)置到推送消息中intent字段的值
Log.d("intentUri", intentUri);
intentUri
開發(fā)者傳參有兩種方法:這些通過本地寫獲取得到intentUri給到服務(wù)端或者網(wǎng)頁端進(jìn)行傳輸
方法1:參數(shù)之間用“&”相連陆淀,其中參數(shù)name=abc與age=180兩個參數(shù)之間用“&”相連。例如:
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?name=abc&age=180"));
方法2:intent直接添加參數(shù):
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
intent.putExtra("name", "abc");
intent.putExtra("age", 180);
2先嬉、App服務(wù)端消息體中指定intent值
服務(wù)端如何發(fā)送消息請參考服務(wù)端開發(fā)指導(dǎo)轧苫。消息體樣例:
{
"message": {
"data": "{'score':'7','time': '16:42'}",
"notification": {
"title": "message title",
"body": "message body"
},
"android": {
"data":"{'androidData':'7','time':'16:42'}",
"notification": {
"click_action": {
"type": 1,
"intent": "intent://com.huawei.codelabpush/deeplink?#Intent;scheme=pushscheme;launchFlags=0x4000000;i.age=180;S.name=abc;end"
}
}
},
"token": [
"pushtoken1"
]
}
}
3、客戶端AndroidManifest.xml文件注冊待啟動的Activity類
參照如下配置注冊自定義的Activity疫蔓,其中host含懊、path、scheme
需與步驟1中協(xié)議的配置相對應(yīng)鳄袍,否則不能跳轉(zhuǎn)到指定的界面绢要。
<activity android:name=".DeeplinkActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="com.huawei.codelabpush"
android:path="/deeplink"
android:scheme="pushscheme" />
</intent-filter>
</activity>
自動初始化1
<application
<meta-data
android:name="push_kit_auto_init_enabled"
android:value="true" />
</application>
自動初始化2
方式2
應(yīng)用顯式調(diào)用HmsMessaging.setAutoInitEnabled(boolean enable)方法,設(shè)置為true即為啟用了自動初始化拗小,反之為未啟用樱哼。設(shè)置后值會保存在應(yīng)用本地的shared_prefs目錄下的文件中。