Как получить доступ к полезной нагрузке push-уведомлений HMS?
Я опубликовал приложение для Android в Huawei AppGallery и могу отправлять push-уведомления с внутреннего сервера приложения через службу HMS Push на мобильный телефон, как описано ниже.
Однако мне интересно, как получить доступ к полезной нагрузке push-уведомления в приложении:
Вот как я сейчас отправляю push-уведомления -
Во-первых, мои серверные 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" ("идентификатор игры" в моем приложении).
В пользовательском классе приемника у меня определены следующие методы, но они не вызываются (кроме onToken
метод - когда мое приложение запускается и асинхронно запрашивает "токен push" из 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);
}
}
Пожалуйста, помогите мне передать пользовательское целочисленное значение из моего бэкэнда в приложение через push-уведомления HMS.
5 ответов
Благодаря хорошей помощи разработчиков Huawei (после отправки им adb shell setprop log.tag.hwpush VERBOSE
log) теперь все решено -
В 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>
В 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;
}
Кстати, я убираю push-уведомления при запуске приложения:
@Override
public void onResume() {
super.onResume();
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancelAll();
}
Наконец, в моем игровом бэкэнде я сначала получаю токен с помощью POSTing на https://login.cloud.huawei.com/oauth2/v2/token.
grant_type=client_credentials&
client_secret=MY_APP_SECRET&
client_id=MY_APP_ID
А затем отправьте POST уведомление https://push-api.cloud.huawei.com/v1/MY_APP_ID/messages:send с использованием заголовковAuthorization: Bearer MY_TOKEN
а также Content-Type: application/x-www-form-urlencoded
. Формат JSON описан в документе HMS PushKit.
{
"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"
Это хорошо работает для моей игры в слова: приходит push-уведомление с заголовком, телом и небольшим изображением. Затем мое приложение открывает игру #108250, когда пользователь нажимает на нее:
Чтобы получить доступ к полезной нагрузке, вам необходимо реализовать класс HmsMessageService и переопределить метод onMessageReceived. Вы можете получить доступ к своей полезной нагрузке из объекта RemoteMessage.
Чтобы получить доступ к токену, переопределите метод onNewToken
Код Java
import android.util.Log;
import com.huawei.hms.push.HmsMessageService;
import com.huawei.hms.push.RemoteMessage;
public class HService extends HmsMessageService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage != null) {
if (!remoteMessage.getData().isEmpty()) {
Log.d("HMS", "Payload" + remoteMessage.getData());
}
if (remoteMessage.getNotification() != null) {
Log.d("HMS", "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
}
}
Код Котлина
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
super.onMessageReceived(remoteMessage)
if (remoteMessage!!.data.isNotEmpty()) {
Log.i(TAG, "Message data payload: " + remoteMessage.data)
}
if (remoteMessage.notification != null) {
Log.i(TAG, "Message Notification Body: " + remoteMessage.notification.body)
}
}
Убедитесь, что вы зарегистрировали свою службу в манифесте.
<service
android:name=".service.HService"
android:enabled="true"
android:exported="true"
android:permission="${applicationId}.permission.PROCESS_PUSH_MSG"
android:process=":HmsMessageService">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
Возможно , это поможет, я нашел его в huaweipushv3.html, только на веб-странице китайской версии по некоторым причинам.
//Intent parameter generation mode:
// Scheme protocol(pushscheme://com.huawei.hms.hmsdemo/deeplink?)needs to be customized by developers
intent.setData(Uri.parse("pushscheme://com.huawei.hms.hmsdemo/deeplink?"));
//Add parameters to the intent as required, eg:"name","abc"
intent.putExtra("name", "abc");
intent.putExtra("age", 180);
//the "flag" must be carried
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);
//The value of intentUri is the value of the intent field in the push message
Log.d("intentUri", intentUri);
также разработчики могут использовать любой из следующих методов для передачи параметров:
//the parameters are connected by "&", for example
intent.setData(Uri.parse("pushscheme://com.huawei.hms.hmsdemo/deeplink?name=abc&age=180"));
//directly add parameters to the intent
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("name", "abc");
intent.putExtra("age", 180);
Объявите определяемую пользователем активность в файле APP AndroidManifest.xml на клиенте, например DeepLinkActivity.
//the value must be consistent with the configuration of the preceding protocol. Otherwise, the specified interface cannot be displayed.
<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.hms.hmsdemo"
android:path="/deeplink"
android:scheme="pushscheme" />
</intent-filter>
</activity>
Параметры приема в классе DeepLinkActivity.
Intent intent = getIntent();
//name corresponds to the parameter abc
String name = intent.getStringExtra("name");
//the value of age corresponds to the value of 180
int age = intent.getIntExtra("age", -1);
Пожалуйста, оставьте сообщение, если у вас возникнут новые вопросы:)
- Вы используете версию 2.0 вашего API. Рекомендуется обновить его до версии 5.0. Откройте указанную страницу приложения, используйте явное намерение, которое может передавать дополнительные данные в приложение.
Вы можете настроить действия, которые будут запускаться, когда пользователи нажимают на сообщения с уведомлениями, например, открытие домашней страницы приложения, доступ к определенному URL-адресу, открытие настроенного мультимедийного содержимого или открытие указанной страницы приложения. Чтобы открыть домашнюю страницу или настраиваемую страницу приложения, требуется совместная работа с устройством и облаком.
Открытие указанной страницы приложения: установка параметра намерения
- Создать параметры намерения
В своем проекте Android Studio создайте намерение, обратившись к следующему коду:
Intent intent = new Intent(Intent.ACTION_VIEW);
// Define a scheme protocol, for example, pushscheme://com.huawei.codelabpush/deeplink?.
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
// Add parameters to Intent as required.
intent.putExtra("name", "abc");
intent.putExtra("age", 180);
// The following flag is mandatory. If it is not added, duplicate messages may be displayed.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);
// The value of intentUri will be assigned to the intent parameter in the message to be sent.
Log.d("intentUri", intentUri);
Вы можете добавить параметры одним из следующих способов:
Используйте амперсанды (&) для разделения пар "ключ-значение".
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?name=abc&age=180"));
Непосредственно добавить параметры в Intent.
intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
intent.putExtra("name", "abc");
intent.putExtra("age", 180);
- Задайте намерение в теле сообщения на вашем сервере приложений Пример тела сообщения:
{
"message": {
"notification": {
"title": "message title",
"body": "message body"
},
"android": {
"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"
]
}
}
- Зарегистрируйте класс Activity для запуска в файле AndroidManifest.xml приложения.
Зарегистрируйте класс Activity, обратившись к следующей конфигурации, где значения хоста, пути и схемы должны быть такими же, как те, которые определены в [Установить намерение в теле сообщения на сервере приложений]. В противном случае указанная страница отображаться не будет.
<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>
- Получать данные в настроенном классе Activity
public class DeeplinkActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_deeplink);
Intent intent = getIntent();
if (null != intent) {
// Obtain data set in method 1.
String name1 = intent.getData().getQueryParameter("name");
int age1 = Integer.parseInt(intent.getData().getQueryParameter("age"));
// Obtain data set in method 2.
String name2 = intent.getStringExtra("name");
int age2 = intent.getIntExtra("age", -1);
Toast.makeText(this, "name " + name1 + ",age " + age1, Toast.LENGTH_SHORT).show();
}
}
}
- Пожалуйста, обратитесь к версии 2.0 push-интерфейса серверов приложений. Используйте поле настройки для передачи параметров, определенных пользователем. Приложение использует метод onEvent для получения пользовательских параметров.
Чтобы обрабатывать сообщение с данными и отображать его как настраиваемое уведомление с большим изображением в push-комплекте HMS (huawei), следуйте приведенной ниже структуре.
- Откройте файл build.gradle в корневом каталоге вашего проекта Android Studio и выполните следующие действия.
buildscript {репозитории { google() jcenter() maven {url 'https://developer.huawei.com/repo/'} } зависимости {classpath 'com.huawei.agconnect:agcp:1.3.1.300'}}
allprojects {репозитории { google() jcenter() maven {url 'https://developer.huawei.com/repo/'} }}
2. Откройте файл build.gradle в каталоге приложения вашего проекта и добавьте зависимости сборки в разделе зависимостей.
dependencies {
implementation 'com.huawei.hms:push:5.0.0.300'
}
Добавьте указанную ниже службу и метаданные в файл манифеста Android внутри приложения.
<meta-data android:name="push_kit_auto_init_enabled" android:value="true"/> <service android:exported="false" android:name=".PushMessage.PushService"> <intent-filter> <action android:name="com.huawei.push.action.MESSAGING_EVENT"/> </intent-filter> </service>
После получения уведомления добавьте приведенный ниже код. Пример сообщения с уведомлением о данных { "message": "тело сообщения", "Title": "добро пожаловать в наше приложение", "ImageURI": "http://api.androidhive.info/images/sample.jpg" } Вы можете найти фрагмент кода - onMessageReceived ()
4.1. Получение растрового изображения из URL -адреса - Функция Вы можете найти фрагмент кода - generatePictureStyleNotification() 4.2. Обработка уведомления
Вы можете найти фрагмент кода - showNotification()
вот полный код в классе PushService
открытый класс PushService расширяет HmsMessageService {
private static final String TAG = "PushService ";
private final static String ACTION = "com.huawei.hms.android.kitdemo.PushMessage.action";
private NotificationManager mNotificationManager;
private static final String CHANNEL1 = "channel1";
public static HashSet<String> mMessages = new HashSet<String>();
private String title, message, imageUrl, msgNotification;
private Bitmap mBitmap = null;
/**
* When an app calls the getToken method to apply for a token from the server,
* if the server does not return the token during current method calling, the server can return the token through this method later.
* This method callback must be completed in 10 seconds. Otherwise, you need to start a new Job for callback processing.
*
* @param token token
*/
@Override
public void onNewToken(String token) {
Log.i(TAG, "received refresh token:" + token);
// send the token to your app server.
if (!TextUtils.isEmpty(token)) {
refreshedTokenToServer(token);
}
System.out.println("Res PushService.onNewToken token - " + token);
}
private void refreshedTokenToServer(String token) {
Log.i(TAG, "sending token to server. token:" + token);
}
/**
* This method is used to receive downstream data messages.
* This method callback must be completed in 10 seconds. Otherwise, you need to start a new Job for callback processing.
*
* @param message RemoteMessage
*/
@Override
public void onMessageReceived(RemoteMessage message) {
Log.i(TAG, "onMessageReceived is called");
if (message == null) {
Log.e(TAG, "Received message entity is null!");
return;
}
String msgNoteBase = message.getData();
System.out.println(TAG + msgNoteBase);
Log.i(TAG, message.getData());
System.out.println(TAG + msgNoteBase);
// {"message":"Check message","Title":"Header","ImageURI":"http://api.androidhive.info/images/sample.jpg"}
new generatePictureStyleNotification(this, msgNoteBase).execute();
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.");
}
@Override
public void onMessageSent(String msgId) {
Log.i(TAG, "onMessageSent called, Message id:" + msgId);
Intent intent = new Intent();
intent.setAction(ACTION);
intent.putExtra("method", "onMessageSent");
intent.putExtra("msg", "onMessageSent called, Message id:" + msgId);
sendBroadcast(intent);
}
@Override
public void onSendError(String msgId, Exception exception) {
Log.i(TAG, "onSendError called, message id:" + msgId + ", ErrCode:"
+ ((SendException) exception).getErrorCode() + ", description:" + exception.getMessage());
Intent intent = new Intent();
intent.setAction(ACTION);
intent.putExtra("method", "onSendError");
intent.putExtra("msg", "onSendError called, message id:" + msgId + ", ErrCode:"
+ ((SendException) exception).getErrorCode() + ", description:" + exception.getMessage());
sendBroadcast(intent);
}
@Override
public void onTokenError(Exception e) {
super.onTokenError(e);
}
// Show the Notification based on the device availabality on foreground or background
@RequiresApi(api = Build.VERSION_CODES.N)
private void showNotification(String msg) {
ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE);
boolean isActivityFound = false;
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
final String packageName = getApplicationContext().getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
isActivityFound = true;
break;
}
}
if (isActivityFound) {
broadcastDialogIntent(msg);
} else {
mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
int notificationId = 1;
String channelId = CHANNEL1;
int importance = NotificationManager.IMPORTANCE_HIGH;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelId, importance);
mNotificationManager.createNotificationChannel(mChannel);
Intent notificationIntent = new Intent(getApplicationContext(), NavigationMainActivity.class);
Bundle passValue = new Bundle();
passValue.putString("msg", msg);
notificationIntent.setAction("android.intent.action.MAIN");
notificationIntent.addCategory("android.intent.category.LAUNCHER");
notificationIntent.putExtras(passValue);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder;
if (mBitmap != null) {
mBuilder = new NotificationCompat.Builder(getApplicationContext(), channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getResources().getString(R.string.app_name))
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(mBitmap)
.bigLargeIcon(mBitmap))
.setContentText(msg);
} else {
mBuilder = new NotificationCompat.Builder(getApplicationContext(), channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getResources().getString(R.string.app_name))
.setContentText(msg);
}
mBuilder.setContentIntent(intent);
mNotificationManager.notify(notificationId, mBuilder.build());
} else {
Intent notificationIntent = new Intent(getApplicationContext(), NavigationMainActivity.class);
Bundle passValue = new Bundle();
passValue.putString("msg", msg);
notificationIntent.setAction("android.intent.action.MAIN");
notificationIntent.addCategory("android.intent.category.LAUNCHER");
notificationIntent.putExtras(passValue);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (mBitmap != null) {
mBuilder.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(getString(R.string.app_name)).setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg)).setContentText(msg).setAutoCancel(true).setSound(soundUri)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(mBitmap)
.bigLargeIcon(mBitmap));
} else {
mBuilder.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(getString(R.string.app_name)).setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg)).setContentText(msg).setAutoCancel(true).setSound(soundUri);
}
mMessages.add(msg);
NotificationCompat.InboxStyle inBoxStyle = new NotificationCompat.InboxStyle();
inBoxStyle.setBigContentTitle(getString(R.string.app_name));
int total = mMessages.size();
if (total == 0) {
setBadge(this, 0);
} else {
setBadge(this, total);
}
Iterator iterator = mMessages.iterator();
while (iterator.hasNext()) {
inBoxStyle.addLine((CharSequence) iterator.next());
}
for (int i = 0; i < total; i++) {
inBoxStyle.addLine(mMessages.toString());
//inBoxStyle.addLine(mMessages.get(total - 1 - i));
}
mBuilder.setContentIntent(intent);
mBuilder.setStyle(inBoxStyle);
Notification notification = mBuilder.build();
mBuilder.setNumber(total);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(notificationId, notification);
}
}
}
/**
* Broadcast dialog intent.
*
* @param msg the msg
*/
public void broadcastDialogIntent(String msg) {
Intent intent = new Intent();
Bundle passValue = new Bundle();
passValue.putString("msg", msg);
intent.putExtras(passValue);
intent.setAction("com.hms.pushdemo.SHOW_DIALOG");
sendBroadcast(intent);
}
/**
* Sets badge.
*
* @param context the context
* @param count the count
*/
public static void setBadge(Context context, int count) {
String launcherClassName = getLauncherClassName(context);
if (launcherClassName == null) {
return;
}
Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
intent.putExtra("badge_count", count);
intent.putExtra("badge_count_package_name", context.getPackageName());
intent.putExtra("badge_count_class_name", launcherClassName);
context.sendBroadcast(intent);
}
/**
* Gets launcher class name.
*
* @param context the context
* @return the launcher class name
*/
public static String getLauncherClassName(Context context) {
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resolveInfos) {
String pkgName = resolveInfo.activityInfo.applicationInfo.packageName;
if (pkgName.equalsIgnoreCase(context.getPackageName())) {
String className = resolveInfo.activityInfo.name;
return className;
}
}
return null;
}
// Get the bitmap from the URL using Glide, where you got from the Data message
private class generatePictureStyleNotification extends AsyncTask<String, Void, Bitmap> {
// {"message":"Check message",
// "Title":"Header",
// "ImageURI":"http://api.androidhive.info/images/sample.jpg"
// }
Context mContext;
public generatePictureStyleNotification(Context context, String msgNoteBase) {
super();
this.mContext = context;
try {
msgNotification = msgNoteBase;
JSONObject mJSONObject = new JSONObject(msgNoteBase);
message = mJSONObject.getString("message");
title = mJSONObject.getString("Title");
imageUrl = mJSONObject.getString("ImageURI");
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
protected Bitmap doInBackground(String... params) {
Glide.with(mContext)
.asBitmap()
.load(imageUrl)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
mBitmap = resource;
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
showNotification(message);
}
}
}
}
Пожалуйста, отнеситесь к этому ответу с недоверием, так как я раньше не использовал службу уведомлений Huawei HMS Push. Однако я столкнулся с подобными проблемами и могу сделать обоснованное предположение относительно того, что вызывает проблему.
Предполагая, что моя логика верна, суть вашей проблемы заключается в том, что HMS Push-уведомления Huawei отправляются с использованием полезной нагрузки JSON, которая не позволяет вашему приложению получить доступ к нему с помощью методов в вашем MyReceiver
учебный класс.
Если вы посмотрите на этот вопрос, вы увидите, что всякий раз, когда полезные данные JSON содержат информацию вnotification
тег, он принимается классом, но не может быть доступен через методы стандартной фоновой службы.
В результате обычные методы доступа к данным не будут работать, потому что полезная нагрузка данных использует структуру, которая обходит доступ в фоновом режиме; поэтому, пока Huawei не изменит способ отправки полезной нагрузки, доступ к ней стандартными средствами невозможен.
Это, как говорится, есть гиды, как этот, которые содержат примеры кода, как это:
if (intent.getData().getScheme().equals("rong") && intent.getData().getQueryParameter("isFromPush") != null) {
if (intent.getData().getQueryParameter("isFromPush").equals("true")) {
String options = getIntent().getStringExtra("options"); // 获取 intent 里携带的附加数据
NLog.d(TAG, "options:", options);
try{
JSONObject jsonObject = new JSONObject(options);
if(jsonObject.has("appData")) { // appData 对应的是客户端 sendMessage() 时的参数 pushData
NLog.d(TAG, "pushData:", jsonObject.getString("appData"));
}
...
...
Который, хотя и из отдельной зависимости, описывает, как можно получить доступ к данным полезной нагрузки с помощью некоторого метода, который Huawei уже использует, через передачу намерения, но, опять же, это просто обоснованное предположение.