Reprint please indicate the source: blog.csdn.net/Chay_Chan/a…

Jump handling of push notifications and message reminders

The message push function is often used in App development, which is used to timely notify users and push relevant information of users’ subscription. This article is not a detailed introduction to how to integrate and use push. As for the introduction of push related knowledge, Guo Shen has published a relevant tutorial on MOOCs. If you want to further study, you can watch guo Shen’s related video.

Results demonstrate

I. App is in running state:

1. After receiving the notification, click the notification to open the demonstration of the corresponding activity:

2. After receiving the notification, click the notification to upload the value and open the demonstration of the corresponding activity:

2. The App process is in the destroyed state, but the background is still running push resident service:

1. After receiving the notification, click the notification to open the corresponding activity. The activity startup process is SplashActivity -> MainActivity -> the corresponding activity

2. After receiving the notification, click the notification to upload the value and open the corresponding activity. The activity startup process is SplashActivity -> MainActivity -> corresponding activity

Related process of push

What I use is a push function of push, push in push this aspect, do relatively good.

  1. Bind push alias, which is usually bound after login. (You can bind the alias of user name push, and the background can push by user name).

This is the demo login:

public void login(View view){ String username = etUsername.getText().toString().trim(); String pwd = etPwd.getText().toString().trim(); If (textutils.isempty (username)){toast.maketext (this," username cannot be empty ", toast.length_short); return; } if (textutils.isempty (PWD)){toast.maketext (this," password cannot be empty ", toast.length_short); return; Pushmanager.getinstance ().bindAlias(this, username); pushManager.getInstance ().bindAlias(this, username) // Bind push alias Preutils.putBoolean (this, Constants.IS_LOGIN,true); / / set to logged-in PreUtils. PutString (this, the ACCOUNT, the username); StartActivity (new Intent(this, mainactivity.class)) = new Intent(this, mainactivity.class); finish(); }Copy the code

2. Unbind the push alias. Generally, the alias is unbound after you log out. (After unbinding, no push using the alias type is received.)

This is the demo logout:

Public void logout(View View){// Exit preutils.putBoolean (this, Constants.IS_LOGIN,false); String username = PreUtils.getString(this, Constants.ACCOUNT, ""); if (! TextUtils.isEmpty(username)){ PushManager.getInstance().unBindAlias(this,username,true); } startActivity(new Intent(this, loginactivity.class)); finish(); }Copy the code

3. Received the background push message: a push support custom message processing, for details, please check the official documents of a push, it is very easy to use. Define a class that inherits GTIntentService, register it in the manifest file, and the onReceiveMessageData () method calls back when a passthrough message is received. Although Individual push can directly push notifications to the Android terminal in the background, iOS terminal can only receive transparent messages. Therefore, an identifier is set in the transparent message. If the message is notification type, the user can create corresponding notifications to display the message after obtaining it.

@Override public void onReceiveMessageData(Context context, GTTransmitMessage msg) { byte[] payload = msg.getPayload(); String message = new String(payload); Log.i(TAG, "onReceiveMessageData: " + message); try { JSONObject jsonObject = new JSONObject(message); int isNotification = jsonObject.optInt(PushConstants.IS_NOTIFICATION); If (isNotification == 1) {// If (isNotification == 1) {showNotification(context, jsonObject); } else {// Alert message dealNotifyMessage(Context, jsonObject); } } catch (JSONException e) { e.printStackTrace(); }}Copy the code

The showNotification () method handles pass-through messages from the notification class:

** @param jsonObject */ private void showNotification(context context, JSONObject jsonObject) { String title = jsonObject.optString(PushConstants.TITLE); String content = jsonObject.optString(PushConstants.CONTENT); if (TextUtils.isEmpty(title) || TextUtils.isEmpty(content)) { return; } int pageNum = jsonObject.optInt(PushConstants.PAGE_NUMBER); String contentId = jsonObject.optString(PushConstants.CONTENT_ID); / / Settings, click on the notification is broadcast, after passing the corresponding data Intent broadcastIntent = new Intent (context, NotificationReceiver. Class); Bundle bundle = new Bundle(); bundle.putInt(PushConstants.PAGE_NUMBER, pageNum); bundle.putString(PushConstants.CONTENT_ID, contentId); broadcastIntent.putExtras(bundle); PendingIntent pendingIntent = PendingIntent. getBroadcast(context, NotificationUtils.getRandowReqCode(), broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationUtils.showIntentNotification(context, title, content, title, pendingIntent, R.mipmap.ic_launcher, R.mipmap.ic_launcher); }Copy the code

The dealNotifyMessage() method deals with pass-through messages of the alert class:

Private void dealNotifyMessage(final context context, JSONObject jsonObject) { int notifyType = jsonObject.optInt(PushConstants.NOTIFY_TYPE, PushConstants.MESSAGE_CENTER_NOTIFY); // Determine the type of the notification message and perform the corresponding UI operation. Since the message is in IntentService, the UI operation needs to be switched between threads. Here we use handler's POST () method to switch switch (notifyType) {case PushConstants.MESSAGE_CENTER_NOTIFY: Handler.post (new Runnable() {public void run() {/* if (mainactivity.instance! = null){ MainActivity.instance.showTabNotify(2); } if (minefragment.ivMessage! = null){ MineFragment.ivMessage.setImageResource(R.mipmap.img_message_unread); Unreaddao.saveorupdate (unreadDao.getunReadCount () + 1); */ log. I (TAG," received message alert, display red dot "); }}); break; }}Copy the code

Notification of click processing

ShowNotification () sets PendingIntent when creating the notification:

/ / Settings, click on the notification is broadcast, after passing the corresponding data Intent broadcastIntent = new Intent (context, NotificationReceiver. Class); Bundle bundle = new Bundle(); bundle.putInt(PushConstants.PAGE_NUMBER, pageNum); Bundle. putString(PUSHConstants.content_id, contentId); bundle.putString(PUSHConstants.content_id, contentId); //id broadcastIntent.putExtras(bundle); PendingIntent pendingIntent = PendingIntent. getBroadcast(context, NotificationUtils.getRandowReqCode(), broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);Copy the code

We through the PendingIntent. GetBroadcast () method to create PendingIntent, need to pass data: PageNum is a page number, defined in PushConstants, which is used to determine which page to jump to, and if it’s a notification of an order, contentId is the id of the corresponding order, which is used to retrieve order data from the order detail page.

When a notification is clicked, a broadcast is sent and a value is passed to the NotificationReceiver, which handles the specific jump operations. Here’s the most important stuff.

NotificationReceiver receives the broadcast after the notification is clicked, calls back in the onReceive() method, retrieves the data passed and processes it accordingly.

@Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); int pageNum = bundle.getInt(PushConstants.PAGE_NUMBER, 0); String contentId = bundle.getString(PushConstants.CONTENT_ID, ""); Intent destinationIntent = null; // Intent switch (pageNum) {case PushConstants.PAGE_ORDER_DETAIL: / / order details page destinationIntent = new Intent (context, OrderDetailActivity. Class); destinationIntent.putExtra(OrderDetailActivity.ORDER_ID, contentId); // Pass the order id break; Case PushConstants. PAGE_MESSAGE_CENTER: / / message center destinationIntent = new Intent (context, MessageCenterActivity. Class); break; } if (SystemUtils.isAppAlive(context, context.getPackagename ())) {// Start the target Activity directly if it is alive, but consider one case: For example, if the user clicks the Back button to exit the app, but the process has not been reclaimed by the system, if the user directly starts the // target Activity, then pressing the Back button will not return the MainActivity. So before starting the target Activity, start the MainActivity first. FLAG_CLEAR_TOP = intent.flag_clear_top = intent.flag_top = intent.flag_top = intent.flag_top = intent.flag_top = intent.flag_top = intent.flag_top = intent.flag_top = intent.flag_top // Create log. I (TAG, "The app process is alive") at the top of the stack if there is no MainActivity instance; Intent mainIntent = new Intent(context, MainActivity.class); mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (intentList == null){ intentList = new ArrayList<Intent>(); } intentList.add(mainIntent); // if the destinationIntent is not empty, open if (destinationIntent! = null){ intentList.add(destinationIntent); } context.startActivities(intentList.toArray(new Intent[intentList.size()])); } else {// If the app process has been killed, restart the app, pass the target Activity's start parameter into the Intent, and pass it through //SplashActivity to MainActivity. I (TAG, "The app process is dead"); log. I (TAG," The app process is dead"); Intent launchIntent = context.getPackageManager(). getLaunchIntentForPackage(context.getPackageName()); launchIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); launchIntent.putExtras(bundle); context.startActivity(launchIntent); }}Copy the code

After receiving the data, determine which activity to start by pageNum (page number). If it is the activity of the order detail page, it needs to pass a contentId (in this case, the ID of the order) as a parameter to obtain the data of the detail page.

It is mainly divided into two cases:

The App process exists and the App process does not exist. The existence of App process can be determined by traversing all running processes in the current mobile phone system and judging whether the package name of the running process is consistent with the package name of the current App.

@param context a context * @param packageName Specifies the name of the application package * @return Boolean */ public static Boolean isAppAlive(Context context, String packageName){ ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses(); for(int i = 0; i < processInfos.size(); i++){ if(processInfos.get(i).processName.equals(packageName)){ Log.i("NotificationLaunch", String.format("the %s is running, isAppAlive return true", packageName)); return true; } } Log.i("NotificationLaunch", String.format("the %s is not running, isAppAlive return false", packageName)); return false; } `Copy the code

Start MainActivity and target Activity regardless of whether the MainActivity is already in the stack. If the MainActivity is already in the stack, start MainActivity and target Activity. The MainActivity startup mode is set to SingleTask, which is used in the stack and clears all activities that are already started at the top of the MainActivity, leaving only the MainActivity (MainActivity is usually low on the stack) and the target activity.

2. When the App process has been killed, click the notification to start the App. The data to be transmitted is passed to the MainActivity through SplashActivity, and the MainActivity determines the target activity to open according to the data. In SplashActivity, check whether getIntent().getextras () is null. If not, pass it to MainActivity.

handler.postDelayed(new Runnable() { @Override public void run() { Intent intent = null; If (Preutils.getBoolean (splashactivity.this, Constants.IS_LOGIN,false)){// If (preutils.getBoolean (splashactivity.this, Constants.IS_LOGIN,false)){ Intent = new intent (splashactivity.this, mainactivity.class); Bundle bundle = getIntent().getExtras(); if (bundle ! MainActivity intent.putextras (bundle) = null){// If the App is not started, click the notification to open the App. }} else {/ / not login, jump login intent = new intent (SplashActivity. This, LoginActivity. Class); } startActivity(intent); }}, 3000);Copy the code

MainActivity does the following:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); . jumpToOtherPage(); } /** * If a message has been received, click the notification to open it. */ private void jumpToOtherPage() {Bundle = getIntent().getextras (); if (bundle ! Int pageNum = bundle.getInt(PushConstants.PAGE_NUMBER, 0); int pageNum = bundle.getInt(PushConstants. String id = bundle.getString(PushConstants.CONTENT_ID, ""); Intent destinationIntent = null; // Intent switch (pageNum) {case PushConstants.PAGE_ORDER_DETAIL: / / order details page destinationIntent = new Intent (this, OrderDetailActivity. Class); destinationIntent.putExtra(OrderDetailActivity.ORDER_ID, id); // Pass the id break of the corresponding order; Case PushConstants. MESSAGE_CENTER_NOTIFY: / / message center page destinationIntent = new Intent (this, MessageCenterActivity. Class); break; } if (destinationIntent ! = null) { startActivity(destinationIntent); }}}Copy the code

So far, about App push notification process is over, but as for the data definition and judgment of the relevant page jump, everyone have their own rules, I here is through the corresponding key defined in PushConstant json constants and page number of constants, the background and the App defines the same constants, At the same time, the corresponding push tool class has been encapsulated, which is applicable to Android and IOS terminals. It should be reminded that IOS needs to configure push certificates in the push management background. About the demo of the demo App and the push demo of the background, you can clone through the following github address, hoping to help you.

Github.com/chaychan/GT… (android)

Github.com/chaychan/GT… (Background Java code)