本来是想吐槽的,写到最好发现官网好清晰
不容易发现的官方API
集成步骤:开发准备官方链接地址
创建应用,添加签名证书
-
- 打开命令行工具(使用CMD命令),执行cd命令进入
keytool.exe
所在的目录
- 打开命令行工具(使用CMD命令),执行cd命令进入
-
- 执行命令
keytool -list -v -keystore
,按命令行提示进行操作。
为应用签名文件的完整路径。填写SHA256
,然后等十几分钟后下载对应的agcibbetct0services.json
文件。
- 执行命令
keytool -list -v -keystore I:\yhxx\releasexxxxx.keystore
添加应用的AppGallery Connect配置文件
a. 登录 AppGallery Connect 网站,选择“我的项目”。
b. 在项目列表中找到您的项目,在项目中点击需要集成HMS SDK的应用。
c. 在“项目设置”页面中,单击“应用”栏下的agconnect-services.json
下载配置文件。
d. 将agconnect-services.json
文件拷贝到应用级根目录下。
配置HMS SDK的maven仓地址
a. 打开AndroidStudio项目级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. 打开应用级module
的build.gradle
文件。
b. 在
dependencies
中添加如下编译依赖。
说明:
{version}
替换为实际的·SDK·版本号:implementation 'com.huawei.hms:push:4.0.3.301'
根据文档来填写,版本号好像更新
dependencies {
//其它已存在的依赖不要删除 implementation 'com.huawei.hms:push:4.0.3.301
implementation 'com.huawei.hms:push:{version}'
}
c. 在应用级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
文件,点击右上方出现Sync Now
等待同步完成。
注册HWPushReceiverService:
配置完成后,可以通过两种方式获取token,一种是清单文件直接加入配置,可以再onNewToken方法里面直接获取,推荐。再一种是设置一下,也是在onNewToken方法中获取token。参考本项目中的类HWPushReceiverService
HWPushReceiverService
类需要开发者自己定义,继承于com.huawei.hms.push.HmsMessageService
类并实现其中的方法。
exported
属性需要设置为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();
}
/**
*
*清单文件设置了自动初始化能力的应用,不需要显式的调用getToken申请token,
* Push SDK会自动申请token,并通过onNewToken回调方法返回。
*/
@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
集成的所有的可能用得到的
配置工程project.properties
文件(不知是否必要,官方写了反正我添加了)
打开您的工程的project.properties
文件,添加如下代码,用于合并子工程中的Manifest
文件。
manifestmerger.enabled=true
集成步骤:[基础能力官方链接地址]
https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/push-basic-capability
基础能力概览
Step1与Step2,开发者的App集成HMS SDK,再调用HmsInstanceId.getToken接口获取到Push Token,请参考申请Push Token章节。
Step3,开发者的App将获取到的Push Token上报到开发者服务器App Provider Server上。
Step4,开发者使用服务器保存的Push Token调用Push服务端提供的API推送Push消息,请参考服务端开发指导章节。
Step5,Push服务器将开发者推送的Push消息发送给Push Token对应的用户设备,设备接收Push消息,请参考接收透传消息章节。
Step6与Step7,Push服务器检测到设备回复消息响应时,将响应状态回执给开发者,开发者需实现消息回执接收能力,请参考服务端开发指导章节。
2. 客户端开发指导
本章节指导开发者完成Push基础能力开发中的客户端开发,通过本开发指导的学习能够帮助开发者快速掌握客户端开发所需的知识技能,快速体验华为Push服务。基础能力客户端开发主要包括如下4个功能点:
1、开发者集成Push SDK后申请Push Token,请参考申请Push Token章节,同时Push SDK 4.0版本我们提供了自动初始化获取token的能力,请参考自动初始化章节
2、开发者App客户端接收服务端推送的Push透传消息,请参考接收透传消息章节
3、是否允许NC(Notification Center)显示通知栏消息,请参考设置是否显示通知栏消息章节
4、自定义点击消息的动作以及向App传递数据可以参考点击通知消息章节
1、调用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如果订阅了主题消息或者服务器主动推送的透传消息(包括通知消息前台展示功能中设置通知消息由应用自己处理
,区别于NC (Notification Center)通知栏消息
),都需要App通过实现onMessageReceived回调方法来接收消息,收到消息的后续行为由应用自己处理
。
重写onMessageReceived
继承于HmsMessageService所复写的方法获取透传
消息数据。
@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 设置是否显示通知栏消息
2.4.1 场景介绍
通知消息是由系统直接在通知中心下拉列表呈现的即时消息。开发者如果想控制应用是否允许显示通知栏消息,可以调用HmsMessaging.turnOnPush或者HmsMessaging.turnOffPush接口。如果开发者不调用此接口,系统默认是允许显示通知栏消息。
HmsMessaging.getInstance(context).turnOnPush().addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(Task task) {
if (task.isSuccessful()) {
Log.i(TAG, "turnOnPush Complete");
} else {
Log.e(TAG, "turnOnPush failed: ret=" + task.getException().getMessage());
}
}
});
2.5 点击通知消息
关于通知消息,开发者可以自定义点击消息的动作,包括:打开App首页、打开特定URL、打开自定义富媒体消息、打开自定义App页面
。其中打开App首页与自定义App页面
需要开发者端云协同开发来完成,下面我们讲下如何实现这两种动作并从服务端接收数据。
注意:
1、点击动作触发打开应用首页或者自定义App页面,都是通过跨应用启动Activity的方式来实现,需要保证要拉起的目标Activity的exported属性为true,即目标Activity要对外界公开,并且无权限保护,这样才能启动成功。
2、通过通知消息传递数据给应用需要推送服务App版本为10.0.0及以上。
2.5.1 打开自定义App页面
打开自定义App页面
有两种方式,一种是通过服务端REST API
指定intent参数,另一种是指定action参数。如果同时指定了两个参数,会优先选取使用intent参数。
指定intent参数
跨应用启动Activity必须使用显式intent方式,通过intent
可以携带额外的数据给客户端App
1、intent参数生成
在AndroidStudio工程中参照如下代码生成intent。
Intent intent = new Intent(Intent.ACTION_VIEW);
// Scheme协议(pushscheme://com.huawei.codelabpush/deeplink?)需要开发者自定义比如:`"wandapushscheme://com.cc.pushallsdk/wandanotify?`content=thisistest")
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
// 往intent中添加参数,用户可以根据自己的需求进行添加参数
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值就是设置到推送消息中intent字段的值
Log.d("intentUri", intentUri);
intentUri
开发者传参有两种方法:这些通过本地写获取得到intentUri给到服务端或者网页端进行传输
方法1:参数之间用“&”相连,其中参数name=abc与age=180两个参数之间用“&”相连。例如:
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?name=abc&age=180"));
方法2:intent直接添加参数:
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
intent.putExtra("name", "abc");
intent.putExtra("age", 180);
2、App服务端消息体中指定intent值
服务端如何发送消息请参考服务端开发指导。消息体样例:
{
"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中协议的配置相对应,否则不能跳转到指定的界面。
自动初始化1
自动初始化2
方式2
应用显式调用HmsMessaging.setAutoInitEnabled(boolean enable)方法,设置为true即为启用了自动初始化,反之为未启用。设置后值会保存在应用本地的shared_prefs目录下的文件中。