How to access payload of HMS push notifications?
Asked Answered
C

6

11

I have published an Android app on Huawei AppGallery and am able to send push notifications from my app backend server via HMS Push Service to the mobile phone as described below.

However, I wonder how to access the push notification payload in the app:

screenshot

Here is how I currently send push notifications -

First, my backend POSTs to https://login.vmall.com/oauth2/token the following:

grant_type=client_credentials&
client_id=MY_APP_ID&
client_secret=MY_APP_SECRET

and successfully gets an access token from HMS backend:

{
"access_token":"CF1/tI97Ncjts68jeXaUmxjmu8BARYGCzd2UjckO5SphMcFN/EESRlfPqhi37EL7hI2YQgPibPpE7xeCI5ej/A==",
"expires_in":604800
}

Then my backend POSTs to (that is URL-encoded for {"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

the following URL-encoded body:

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

where the payload value is (and I am not sure, if it has a correct JSON structure and what does "type" 3 really mean):

{
  "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
    }
  }
}

I need to extract the custom integer "gid" value (the "game id" in my app).

In the custom receiver class I have the following methods defined, but they are not called (except the onToken method - when my app launches and async requests the "push token" from HMS by calling HuaweiPush.HuaweiPushApi.getToken method):

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);
    }
}

Please help me to pass a custom integer value from my backend to the app via HMS push notifications.

Clunk answered 9/9, 2019 at 20:27 Comment(0)
C
4

Thanks to the nice help provided by Huawei developers (after sending them an adb shell setprop log.tag.hwpush VERBOSE log) everything is resolved now -

In AndroidManifest.xml I have added a custom scheme app (could be any string) as explained in the 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>

In MainActivity.java I have added a code for parsing intents:

@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;
}

By the way I clear push notifications when the app is started:

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

    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    manager.cancelAll();
}

Finally in my game backend I first acquire token by POSTing to https://login.cloud.huawei.com/oauth2/v2/token

grant_type=client_credentials&
client_secret=MY_APP_SECRET&
client_id=MY_APP_ID

And then POST the notification https://push-api.cloud.huawei.com/v1/MY_APP_ID/messages:send using the headers Authorization: Bearer MY_TOKEN and Content-Type: application/json; charset=UTF-8. The JSON format is described at HMS PushKit doc.

{ 
   "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"
      ]
   }
}

The HMS SDKs I currently use in my build.gradle currently are:

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"

This works well for my word game: a push notification arrives, with the title, body and small image. Then the game #108250 is opened by my app, when the user taps it:

app screenshot

Clunk answered 1/2, 2020 at 20:35 Comment(5)
It is not advised to have your credentials included in your APK, rather use a sever to send requests to which then in return sends the push notification. I can now download your APK, decompile it, get your credentials, and ruin your day.Octane
Well, you can hardly ruin my day, because the HMS credentials are obviously stored in my game backend. Maybe you do not understand the whole picture, how the backend (and not the app) sends POST requests to HMS servers - to acquire a token and then to send push notification.Clunk
Well maybe not. Just wanted to make sure. A lot of people do store their credentials in their apps which is not advisable.Octane
Thanks for this guide, it's helpful. I found one inconsistency with HMS documentation: notification request should use Content-Type: application/json; charset=UTF-8 instead of form-urlencodedLogsdon
I have changed the Content-Type in my answer, thanksClunk
P
3

In order to access the payload, you need to implement HmsMessageService class and override the method onMessageReceived. You can access your payload from the RemoteMessage Object.

To access the token, override the onMessageReceived function

Java code

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());
            }
        }
    }
}

Kotlin Code

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)
        }
    }

Please ensure to register your service in the manifest.

        <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>
Platform answered 28/10, 2019 at 11:31 Comment(0)
T
2

maybe this will help, i found it in the huaweipushv3.html, only in the Chinese version web-page cuz some reasons.

//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);

also, developers can use either of the following methods to transfer parameters:

//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);

Declare the user-defined activity in the APP AndroidManifest.xml file on the client, for example, 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>

Receive parameters in the DeepLinkActivity class.

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); 

Please leave a message if you have any new questions :)

Tristan answered 18/11, 2019 at 2:38 Comment(0)
M
1
  1. You are using the Version 2.0 of your API. You are advised to upgrade it to Version 5.0. Open the specified Page of an App, use an explicit Intent, which can transfer extra data to the app.

You can customize the actions to be triggered when users tap notification messages, such as opening the home page of an app, accessing a specific URL, opening customized rich media, or opening a specified page of an app. Opening the home page or a custom page of an app requires device-cloud collaboration.

Opening a Specified Page of an App: Setting the intent Parameter

  • Generate Intent parameters

In your Android Studio project, create Intent by referring to the following code:

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);

You can add parameters in either of the following methods:

Use ampersands (&) to separate key-value pairs.

intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?name=abc&age=180"));

Directly add parameters to the Intent.

intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
intent.putExtra("name", "abc");
intent.putExtra("age", 180);
  • Set intent in the message body on your app server Message body example:
    {
        "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"
            ]
        }
    }
  • Register the Activity class to be started in the AndroidManifest.xml file of the app

Register the Activity class by referring to the following configuration, where the values of host, path, and scheme must be the same as those defined in [Set intent in the message body on your app server]. Otherwise, the specified page will not 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.codelabpush"
            android:path="/deeplink"
            android:scheme="pushscheme" />
    </intent-filter>
</activity>
  • Receive data in the customized Activity class
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();
        }
    }
}
  1. Please kindly refer to Version 2.0 of App Servers push interface. Use the customize field to transfer user-defined parameters. The app uses the onEvent method to obtain user-defined parameters.
Macknair answered 28/9, 2020 at 10:46 Comment(0)
S
0

Please take this answer with a grain of salt as I have not used Huawei's HMS Push notification service before. I have, however, ran into this type of an issue and can make an educated guess as to what is causing the problem.

Assuming my logic is correct, the core of your issue is that Huawei's HMS Push Notifications are being sent using a JSON payload that prevents your app from accessing it via the methods in your MyReceiver class.

If you look at this question you will see that whenever the JSON data payload contains info in the notification tag, it is received by the class, but cannot be accessed via the methods in the standard background service.

The upshot here is that normal methods for accessing the data won't work because the data payload is using a structure that bypasses access in the background; so until Huawei changes how the payload is sent, it cannot be accessed by standard means.

That being said, there are guides like this one that contain sample code like this:

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"));
            }
      ... 
      ...

Which although from a separate dependency, outlines how it may be possible to access the payload data using some method that Huawei already has in place via an intent pass, but again, this is just an educated guess.

Sarcastic answered 18/9, 2019 at 20:9 Comment(0)
S
0

In order to handle data message and show as custom notification with big image in HMS push kit (huawei) please follow structure below

  1. Open the build.gradle file in the root directory of your Android Studio project and do as below.
buildscript {
    repositories {
        google()
        jcenter()
        maven {url 'https://developer.huawei.com/repo/'}
    }
    dependencies {
        classpath 'com.huawei.agconnect:agcp:1.3.1.300'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven {url 'https://developer.huawei.com/repo/'}
    }
}
  1. Open the build.gradle file in the app directory of your project and Add build dependencies in the dependencies section

    dependencies {
        implementation 'com.huawei.hms:push:5.0.0.300'
    }
    
  2. Add the below service and meta-data in Android manifest file inside the application

     <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>
    
  3. After getting the notification please add the below code. Sample Data Notification message

     {
       "message": "body message",
       "Title": "welcome to our app",
       "ImageURI": "http://api.androidhive.info/images/sample.jpg"
     }
    

    You can find the code snippet- onMessageReceived()

4.1. Get bitmap from the URL - Function You can find the code snippet- generatePictureStyleNotification()

4.2. Handling the Notification
You can find the code snippet - showNotification()

Here is full code in PushService class

public class PushService extends 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);
            }
        }
    }


}

enter image description here

Scrappy answered 14/8, 2020 at 6:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.