android - 如何访问HMS推送通知的payload?
问题描述
我已经在华为 AppGallery 上发布了一个 Android 应用程序,并且能够通过HMS 推送服务从我的应用程序后端服务器向手机发送推送通知,如下所述。
但是,我想知道如何在应用程序中访问推送通知有效负载:
这是我目前发送推送通知的方式 -
首先,我的后端 POST 到https://login.vmall.com/oauth2/token如下:
grant_type=client_credentials&
client_id=MY_APP_ID&
client_secret=MY_APP_SECRET
并成功从 HMS 后端获取访问令牌:
{
"access_token":"CF1/tI97Ncjts68jeXaUmxjmu8BARYGCzd2UjckO5SphMcFN/EESRlfPqhi37EL7hI2YQgPibPpE7xeCI5ej/A==",
"expires_in":604800
}
然后我的后端 POST 到(即 URL 编码的{"ver":"1", "appId":"MY_APP_ID"}
) -
https://api.push.hicloud.com/pushsend.do?nsp_ctx=
%7B%22ver%22%3A%221%22%2C+%22appId%22%3A%22101130655%22%7D
以下 URL 编码的正文:
access_token=CF1/tI97Ncjts68jeXaUmxjmu8BARYGCzd2UjckO5SphMcFN/EESRlfPqhi37EL7hI2YQgPibPpE7xeCI5ej/A==
&nsp_svc=openpush.message.api.send
&nsp_ts=1568056994
&device_token_list=%5B%220869268048295821300004507000DE01%22%5D
&payload=%7B%22hps%22%3A%7B%22msg%22%3A%7B%22action%22%3A%7B%22param%22%3A%7B%22appPkgName%22%3A%22de%2Eslova%2Ehuawei%22%7D%2C%22type%22%3A3%7D%2C%22type%22%3A3%2C%22body%22%3A%7B%22title%22%3A%22Alexander%3A+How+to+access+payload%3F%22%2C%22content%22%3A%22Alexander%3A+How+to+access+payload%3F%22%7D%7D%2C%22ext%22%3A%7B%22gid%22%3A86932%7D%7D%7D
值在哪里payload
(我不确定它是否具有正确的 JSON 结构以及“类型”3 的真正含义):
{
"hps": {
"msg": {
"action": {
"param": {
"appPkgName": "de.slova.huawei"
},
"type": 3
},
"type": 3,
"body": {
"title": "Alexander:+How+to+access+payload?",
"content": "Alexander:+How+to+access+payload?"
}
},
"ext": {
"gid": 86932
}
}
}
我需要提取自定义整数“gid”值(我的应用程序中的“游戏 id”)。
在自定义接收器类中,我定义了以下方法,但没有调用它们(onToken
方法除外 - 当我的应用程序启动并异步通过调用方法从 HMS 请求“推送令牌”时HuaweiPush.HuaweiPushApi.getToken
):
public class MyReceiver extends PushReceiver {
private final static String BELONG_ID = "belongId";
@Override
public void onToken(Context context, String token, Bundle extras) {
String belongId = extras.getString(BELONG_ID);
Log.d(TAG, "onToken belongId=" + belongId + ", token=" + token);
}
// this method is called for transparent push messages only NOT CALLED
@Override
public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {
String content = new String(msg, "UTF-8");
Log.d(TAG, "onPushMsg content=" + content);
return true;
}
// this method is when a notification bar message is clicked NOT CALLED
@Override
public void onEvent(Context context, Event event, Bundle extras) {
if (Event.NOTIFICATION_OPENED.equals(event) || Event.NOTIFICATION_CLICK_BTN.equals(event)) {
int notifyId = extras.getInt(BOUND_KEY.pushNotifyId, 0);
Log.d(TAG, "onEvent notifyId=" + notifyId);
if (notifyId != 0) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(notifyId);
}
}
String msg = extras.getString(BOUND_KEY.pushMsgKey);
Log.d(TAG, "onEvent msg=" + msg);
super.onEvent(context, event, extras);
}
// this method is called when push messages state changes
@Override
public void onPushState(Context context, boolean pushState) {
Log.d(TAG, "onPushState pushState=" + pushState);
}
}
请帮助我通过 HMS 推送通知将自定义整数值从我的后端传递到应用程序。
解决方案
感谢华为开发人员提供的帮助(在向他们发送adb shell setprop log.tag.hwpush VERBOSE
日志后),现在一切都已解决 -
在AndroidManifest.xml中,我添加了一个自定义方案app
(可以是任何字符串),如 Google doc Create Deep Links to App Content中所述:
<activity android:name="de.slova.MainActivity">
<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:scheme="app" android:host="slova.de" />
</intent-filter>
</activity>
在MainActivity.java我添加了用于解析意图的代码:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// getIntent() should always return the most recent intent
handleIntent(intent);
}
private boolean handleIntent(Intent intent) {
try {
String gidStr = intent.hasExtra("gid") ?
intent.getStringExtra("gid") : // FCM notification
intent.getData().getQueryParameter("gid"); // HMS notification
Log.d(TAG, "handleIntent gidStr=" + gidStr);
int gid = Integer.parseInt(gidStr);
// show the game when user has tapped a push notification
showGame(gid);
return true;
} catch (Exception ex) {
Log.w(TAG, "handleIntent", ex);
}
return false;
}
顺便说一句,我在应用程序启动时清除推送通知:
@Override
public void onResume() {
super.onResume();
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancelAll();
}
最后在我的游戏后端,我首先通过 POST 到https://login.cloud.huawei.com/oauth2/v2/token获取令牌
grant_type=client_credentials&
client_secret=MY_APP_SECRET&
client_id=MY_APP_ID
然后使用 headers和POST 通知https://push-api.cloud.huawei.com/v1/MY_APP_ID/messages:send。JSON 格式在HMS PushKit文档中描述。Authorization: Bearer MY_TOKEN
Content-Type: application/json; charset=UTF-8
{
"message": {
"android": {
"notification": {
"image": "https://slova.de/ws/board3?gid=108250",
"title": "Game 108250",
"body": "Alexander: Test chat msg",
"click_action": {
"type": 1,
"intent": "app://slova.de/?gid=108250"
}
}
},
"token": [
"1234567890123456789000000000DE01"
]
}
}
我目前在build.gradle中使用的 HMS SDK有:
implementation "com.huawei.hms:base:3.0.0.301"
implementation "com.huawei.hms:hwid:3.0.0.301"
implementation "com.huawei.hms:push:3.0.0.301"
implementation "com.huawei.hms:iap:3.0.0.301"
这对我的文字游戏很有效:推送通知到达,带有标题、正文和小图像。然后游戏#108250 由我的应用程序打开,当用户点击它时:
推荐阅读
- spring - Spring Task Executor 线程数不断增加
- python - 我在 Python 中使用 EmailMessage 练习电子邮件
- r - 编程一个函数来显示飞镖游戏中可能的完成
- sql - 在 oracle sql 中使用 regexp_replace 标准化地址
- javascript - 错误:使用 toFixed() 无法将类型“字符串”分配给类型“数字”
- java - 如何在java中按字母顺序对列表进行排序?
- email - Gmail:电子邮件签名太长:少于 10,000 个字符
- javascript - v-for 中的 Vue Js 文本输入都返回相同的输入
- swift - 将字符串更改为代码文本的可能性?
- python - While 语句继续循环,即使它在技术上不应该是可能的