如何访问非透明HMS推送通知的有效负载?

Ale*_*ber 5 android push-notification huawei android-push-notification huawei-mobile-services

我已经在Huawei AppGallery上发布了一个Android应用程序,并且能够通过HMS Push Service从我的应用程序后端服务器向手机发送推送通知(非透明),如下所述。

但是,我想知道如何在应用程序中访问推送通知有效内容

屏幕截图

这是我目前发送推送通知的方式-

首先,我到https://login.vmall.com/oauth2/的后端POST标记以下内容:

grant_type=client_credentials&client_id=101130655&client_secret=XXXXX
Run Code Online (Sandbox Code Playgroud)

并成功从HMS后端获取访问令牌:

{
"access_token":"CF1/tI97Ncjts68jeXaUmxjmu8BARYGCzd2UjckO5SphMcFN/EESRlfPqhi37EL7hI2YQgPibPpE7xeCI5ej/A==",
"expires_in":604800
}
Run Code Online (Sandbox Code Playgroud)

然后,我的后端POST到(对进行URL编码{"ver":"1", "appId":"101130655"})-

https://api.push.hicloud.com/pushsend.do?nsp_ctx=
    %7B%22ver%22%3A%221%22%2C+%22appId%22%3A%22101130655%22%7D
Run Code Online (Sandbox Code Playgroud)

以下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
Run Code Online (Sandbox Code Playgroud)

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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我需要提取自定义整数“ gid”值(我的应用中的“游戏ID”)。

在自定义接收器类中,我定义了以下方法,但未调用它们(该onToken方法除外-当我的应用启动并通过调用HuaweiPush.HuaweiPushApi.getToken方法异步从HMS请求“推送令牌”时):

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

请帮助我通过HMS推送通知将自定义整数值从后端传递到应用程序。

更新:

点击通知时,我尝试getIntent().toUri(0)onCreate应用中打印,但是我仅看到以下内容:

#Intent;action=android.intent.action.MAIN;
category=android.intent.category.LAUNCHER;
launchFlags=0x30020000;
package=de.slova.huawei;
component=de.slova.huawei/de.slova.MainActivity;end
Run Code Online (Sandbox Code Playgroud)

Ale*_*ber 4

感谢华为开发人员提供的良好帮助(在向他们发送日志后adb shell setprop log.tag.hwpush VERBOSE),现在一切都解决了 -

AndroidManifest.xml中,我添加了一个自定义方案app(可以是任何字符串),如 Google 文档创建应用程序内容的深层链接中所述:

<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>
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我在应用程序启动时清除推送通知:

@Override
public void onResume() {
    super.onResume();

    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    manager.cancelAll();
}
Run Code Online (Sandbox Code Playgroud)

最后,在我的游戏后端,我首先通过 POST 到https://login.cloud.huawei.com/oauth2/v2/token来获取令牌

grant_type=client_credentials&
client_secret=MY_APP_SECRET&
client_id=MY_APP_ID
Run Code Online (Sandbox Code Playgroud)

然后使用 headers和来 POST 通知https://push-api.cloud.huawei.com/v1/MY_APP_ID/messages:send。JSON格式在HMS PushKit文档中有描述。Authorization: Bearer MY_TOKENContent-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"
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)

目前我的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"
Run Code Online (Sandbox Code Playgroud)

这对于我的文字游戏很有效:推送通知到达,带有标题、正文和小图像。然后,当用户点击游戏 #108250 时,我的应用程序将打开它:

应用程序截图

  • 感谢您的指导,它很有帮助。我发现与HMS文档不一致的地方:通知请求应该使用 `Content-Type: application/json; charset=UTF-8` 而不是 `form-urlencoded` (2认同)