大概整理步骤4步
首先需要在华为开发者联盟平台注册账号
进入 “管理中心” -> “应用管理”,点击 “创建移动应用” 按钮,填写必要的信息,创建一个应用
需要为创建的应用程序申请Push权益
进入 “管理中心” -> “应用管理”,点击权益列的 “+” 打开 “配置权益”对话框,申请需要的Push权益
申请 Push权益时,需要提供应用签名证书的 SHA256 指纹
在命令行使用 keytool -list -v -keystore < keystore-file > 命令
< keystore-file > 是为应用签名使用的 keystore 文件,当提示输入口令时,可以选择不输入不影响获得 SHA256 指纹
注意:keytool 命令是”%JAVA_HOME%\bin\keytool.exe”下的命令符想要正常接收通知,如果不是华为手机,需要安装 “华为服务”才可以接收通知
集成华为推送有两种方式
- HMS Push (本文使用HMS方式集成)
- Push SDK
注意:
HMS Push 的接口可以全量替换老版本的 Push 接口
APP 不能同时集成 HMS Push 和老的 Push SDK, 如果使用 HMS Push,必须删除老的 Push SDK 代码和 jar 包
切换到 HMS Push 后,原来的 setTag/getTag/deleteTag 功能暂时不可用,如果 APP需要使用到这 3 个接口功能,那建议先不要切换,等后续 HMS 版本支持了再切换
相关文件配置
- 配置 manifest 文件
<!-- 必需的权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- 保存富媒体消息需要,无富媒体消息则不需要 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 创建桌面快捷方式,无富媒体消息则不需要 -->
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<!-- 根据地理位置推送消息需要事先上报地理位置信息,需要如下权限,不上报则不需要-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 访问Push APK provider需要的权限,SDK富媒体需要,无富媒体功能则不需要 -->
<uses-permission android:name="com.huawei.pushagent.permission.RICHMEDIA_PROVIDER"/>
配置APPID
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="appid">
</meta-data>
其中meta-data中,指定了应用ID,"appid"用实际申请的应用ID替换
<!-- 升级provider,向安装器提供 "content://<package.name>.hsf.update.provider/update/hms/HwMobileService.apk" -->
<provider
android:name="com.huawei.hms.update.provider.UpdateProvider"
android:authorities="您的包名.hms.upda te.provider"
android:exported="false"
android:grantUriPermissions="true"/>
<!-- 第三方相关 :接收Push消息(注册、Push消息、Push连接状态)广播 -->
<receiver android:name=".receiver.HuaweiPushReceiver">
<intent-filter>
<!-- 必须,用于接收token -->
<action android:name="com.huawei.android.push.intent.REGISTRATION"/>
<!-- 必须,用于接收消息 -->
<action android:name="com.huawei.android.push.intent.RECEIVE"/>
<action android:name="com.huawei.android.push.intent.CLICK"/>
<!-- 可选,查看push通道是否连接,不查看则不需要 -->
<action android:name="com.huawei.intent.action.PUSH_STATE"/>
</intent-filter>
<meta-data
android:name="CS_cloud_ablitity"
android:value="@string/hwpush_ability_value"/>
</receiver>
<receiver
android:name="com.huawei.hms.support.api.push.PushEventReceiver">
<intent-filter>
<!-- 接收通道发来的通知栏消息,兼容老版本Push -->
<action android:name="com.huawei.intent.action.PUSH"/>
</intent-filter>
</receiver>
- 申请 token
应用在调用 Push 接口前需要先连接到华为移动服务(HMS),进行接口鉴权,接口鉴
权成功之后才能调用 push 接口
创建HuaweiApiClient实例,连接到华为移动服务
HuaweiApiClient client = new HuaweiApiClient.Builder(this) //
.addApi(HuaweiPush.PUSH_API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
//获取token示例代码--同步调用方式
private void getToken() {
if (!isConnected()) {
Log.e("TAG","get token failed, HMS is disconnect");
return;
}
new Thread() {
@Override
public void run() {
PendingResult<TokenResult> tokenResult =
HuaweiPush.HuaweiPushApi.getToken(huaweiApiClient);
//token结果通过广播返回,不通过pendingResult返回,调用await()方法发起请求根据对象可以获取接口调用是否成功,但是不直接返回token结果
tokenResult.await();
}
}.start();
}
//获取token--异步调用方式
private void getToken(){
final PendingResult<TokenResult> tokenResult = HuaweiPush.HuaweiPushApi.getToken(huaweiApiClient);
tokenResult.setResultCallback(new ResultCallback<TokenResult>() {
@Override
public void onResult(TokenResult result) {
Log.e(TAG,"tokenResult.setResultCallback() thread:" +Thread.currentThread().getName());
new Thread() {
@Override
public void run() {
tokenResult.await();
}
}.start();
}
});
}
【注意事项】
调用申请token前,HuaweiApiClient必须是连接成功的。
采用同步调用方式时,await()方法不能在主线程里调用。
Token结果通过广播返回,详见PushReceiver 的onToken()实现
申请不到 token?
申请不到 token的原因有多种,最常见的是接口鉴权失败或应用证书指纹校验错误
(1)接口鉴权失败,返回 6XXX 错误先检查网络是否正常连接,检查应用是否已经在开发者联盟上面开通Push权益
(2)接口鉴权失败,返回 9071357XX 错误不允许使用Push能力联盟上的证书指纹与应用的证书指纹不匹配
(3)华为服务需要有自启动权限
(4)如果集成正确,则需要在客户端抓取日志,查看具体的失败原因,先使用该设备(申请不到 token 的设备)安装运行下载文档中提供的demo,调用申请token 接口,确认是否可以获取到 token。如果可以获取到说明设备没问题,很可能是app集成HMS SDK时出错.如果设备可以连接adb环境,请使用工具抓取日志并将日志发送给华为接口人,工具可以咨询华为接口人并获取
ok,到此就可以通过华为开发者联盟平台进行推送消息了
集成 PushReceiver 接收 token,Push 连接状态等
应用需要创建一个子类继承com.huawei.hms.support.api.push.PushReceiver,实现onToken(),onPushState(),onPushMsg(),onEvent()这几个抽象方法,用来接收 token返回,push连接状态,透传消息和通知栏点击事件处理
public void onToken(Context context, String token, Bundle extras) {
String belongId = extras.getString("belongId");
String content = "获取token和belongId成功,token = " + token + ",belongId = " +
belongId;
Log.d(PushMainActivity.TAG, content);
// TODO
}
public void onPushState(Context context, boolean pushState) {
try {
String content = "查询push通道状态: " + (pushState ? "已连接" : "未连接");
Log.d("PushLog", content);
showPushMessage(PushMainActivity.RECEIVE_STATUS_MSG, content);
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {
try {
String content = "收到一条Push消息: " + new String(msg, "UTF-8");
Log.d(PushMainActivity.TAG, content);
showPushMessage(PushMainActivity.RECEIVE_PUSH_MSG, content);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void onEvent(Context context, Event event, Bundle extras) {
//NOTIFICATION_OPENED,通知栏中的通知被点击打开
//NOTIFICATION_CLICK_BTN,通知栏中通知上的按钮被点击
if (Event.NOTIFICATION_OPENED.equals(event) ||
Event.NOTIFICATION_CLICK_BTN.equals(event)) {
int notifyId = extras.getInt(BOUND_KEY.pushNotifyId, 0);
if (0 != notifyId) {
NotificationManager manager = (NotificationManager)context
.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(notifyId);
}
String content = "收到通知附加消息:"+extras.getString(BOUND_KEY.pushMsgKey);
Log.d(PushMainActivity.TAG, content);
showPushMessage(PushMainActivity.RECEIVE_NOTIFY_CLICK_MSG, content);
}
super.onEvent(context, event, extras);
}
透传消息和通知栏消息有什么区别?
透传消息是华为 Push 将消息送达手机后不做呈现,直接转给开发者的应用,由应用本
身去解析消息和呈现内容。
通知栏消息是华为 Push 将消息送达手机后,会在通知栏显示一条消息,点击后触发指
定动作,应用不需要去解析消息和控制呈现,减少了应用的开发工作量。