█ 【安卓學習之第三方庫】 消息推送之極光推送
█ 相關文章:
-
● 【安卓學習之第三方庫】庫的使用2-jar類庫的使用(以dom4j爲例)和升級(以極光推送爲例)
█ 讀前說明:
-
● 本文通過學習別人寫demo,學習一些課件,參考一些博客,’學習相關知識,如果涉及侵權請告知
● 本文只簡單羅列相關的代碼實現過程
● 涉及到的邏輯以及說明也只是簡單介紹,主要當做筆記,瞭解過程而已
█ 阿里雲後臺:
-
● 進入阿里雲移動研發平臺EMAS控制檯,點擊【登錄】按鈕,進入控制檯
● 移動推送,開發文檔:
● 後臺創建應用
PS:同一個產品下的多個應用的AppKey是不同的
● 免費30分鐘遠程真機測試:
● 推送設置,Maven庫快速集成(遠程同步)的方式很簡單,其他在創建的時候就已經給開發者做了引導
Android SDK 3.0配置集成開發文檔
Android EMAS統一接入
com.alibaba.app.appkey和com.alibaba.app.appsecret爲您App的對應信息,在推送控制檯APP列表頁的應用證書中獲取。appkey和appsecret請務必寫在application標籤下,否則sdk會報找不到appkey錯誤。如果您是百川雲推送用戶,不能直接使用百川平臺的appKey和appSecret,需要登錄阿里雲移動推送控制檯,登錄賬號爲您的百川平臺賬號,並使用阿里雲平臺的appKey,appSecret。
自V3.1.2版本開始,push支持EMAS統一接入功能,接入該功能無需再在AndoridManifest文件中設置appkey, appsecret
● 推送測試,下載demo或者集成sdk後,在沒有後臺配合的情況下,就可以直接通過該界面進行推送測試,正常主要都是用【推送消息】(一般都是json字符串,再轉換成對象),當然也可以用【推送通知】。
● 推送歷史查看:
● app測試,進入跟着Demo快速體驗移動推送,下載阿里雲移動推送Demo APP Android版,界面如下:
● app測試,收到消息推送,含【推送通知】和【推送消息】:
█ demo結構:
-
● demo下載後,工程名爲:JPushExample(1630873),打開工程,代碼目錄如下:
● build.gradle文件如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.xxx.xxxx"// 值來自開發者平臺設置的【應用包名】
minSdkVersion 9
targetSdkVersion 26
versionCode 360
versionName "3.6.0"
manifestPlaceholders = [
JPUSH_APPKEY : "012345678901234567890123",//值來自開發者平臺取得的【AppKey】
JPUSH_CHANNEL: "default_developer",
]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
● AndroidManifest.xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.jpushdemo"// 注意,這個包名可以和平臺設置的【應用包名】不一樣,是假包名
>
<application
android:icon="@drawable/ic_launcher"
android:allowBackup="false"
android:label="@string/app_name"
android:name="com.example.jpushdemo.ExampleApplication"
tools:ignore="GoogleAppIndexingWarning">
<!-- User defined. For test only 用戶自定義的廣播接收器-->
<receiver
android:name="com.example.jpushdemo.MyReceiver"
android:enabled="true">
<intent-filter>
<action android:name="cn.jpush.android.intent.REGISTRATION" /> <!--Required 用戶註冊SDK的intent-->
<action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" /> <!--Required 用戶接收SDK消息的intent-->
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" /> <!--Required 用戶接收SDK通知欄信息的intent-->
<action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" /> <!--Required 用戶打開自定義通知欄的intent-->
<action android:name="cn.jpush.android.intent.CONNECTION" /><!-- 接收網絡變化 連接/斷開 since 1.6.3 -->
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<!-- User defined. For test only 用戶自定義接收消息器,3.0.7開始支持,目前新tag/alias接口設置結果會在該廣播接收器對應的方法中回調-->
<!--since 3.3.0 接收JPush相關事件-->
<!-- Required since 3.0.7 -->
<!-- 新的 tag/alias 接口結果返回需要開發者配置一個自定的廣播 -->
<!-- 3.3.0開始所有事件將通過該類回調 -->
<!-- 該廣播需要繼承 JPush 提供的 JPushMessageReceiver 類, 並如下新增一個 Intent-Filter -->
<receiver android:name="com.example.jpushdemo.PushMessageReceiver">
<intent-filter>
<action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
<category android:name="${applicationId}"></category>
</intent-filter>
</receiver>
</application>
</manifest>
█ demo講解:
-
● 首頁需要在Application中進行初始化JPush(如果已經初始化JPush,但沒有登錄成功,則執行重新登錄):
JPushInterface.setDebugMode(true); // 設置開啓日誌,發佈時請關閉日誌
JPushInterface.init(this); // 初始化 JPush
● 初始化後,就可以開始接收推送消息,這邊我們注意到兩個文件:
MyReceiver:用戶自定義的廣播接收器
PushMessageReceiver:用戶自定義接收消息器,3.0.7開始支持,
注 : **從JPush3.0.7開始,需要配置繼承JPushMessageReceiver的廣播,原來如果配了MyReceiver現在可以棄用
● 觀察可以發現這兩個文件其實是一樣的,MyReceiver是將所有的消息處理都在同一個方法中,想要知道是什麼事件,需要自己取值判斷,而PushMessageReceiver是將不同的消息處理放在不同的方法中,提前給你分類了:
這邊重點關注4個地方:【自定義消息】推送處理、【發送通知】推送處理、【發送通知】通知打開處理、和極光服務器的連接狀態。
public class MyReceiver extends BroadcastReceiver {
private static final String TAG = "JIGUANG-Example";
@Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
Logger.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));
if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
Logger.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
//send the Registration Id to your server...
} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
Logger.d(TAG, "[MyReceiver] 接收到推送下來的自定義消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
// ######################【自定義消息】推送處理######################
} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
Logger.d(TAG, "[MyReceiver] 接收到推送下來的通知");
int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
Logger.d(TAG, "[MyReceiver] 接收到推送下來的通知的ID: " + notifactionId);
// ######################【發送通知】推送處理######################
} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
Logger.d(TAG, "[MyReceiver] 用戶點擊打開了通知");
// ######################【發送通知】通知打開處理######################
} else if(JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {
boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);
Logger.w(TAG, "[MyReceiver]" + intent.getAction() +" connected state change to "+connected);
// ######################和極光服務器的連接狀態######################
} else {
Logger.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());
}
} catch (Exception e){
}
}
}
public class PushMessageReceiver extends JPushMessageReceiver{
private static final String TAG = "PushMessageReceiver";
// ######################【自定義消息】推送處理######################
@Override
public void onMessage(Context context, CustomMessage customMessage) {
Log.e(TAG,"[onMessage] "+customMessage);
processCustomMessage(context,customMessage);
}
// ######################【發送通知】通知打開處理######################
@Override
public void onNotifyMessageOpened(Context context, NotificationMessage message) {
Log.e(TAG,"[onNotifyMessageOpened] "+message);
}
// ######################【發送通知】按鈕處理######################
@Override
public void onMultiActionClicked(Context context, Intent intent) {
Log.e(TAG, "[onMultiActionClicked] 用戶點擊了通知欄按鈕");
}
// ######################【發送通知】推送處理######################
@Override
public void onNotifyMessageArrived(Context context, NotificationMessage message) {
Log.e(TAG,"[onNotifyMessageArrived] "+message);
}
// ######################和極光服務器的連接狀態######################
@Override
public void onConnected(Context context, boolean isConnected) {
Log.e(TAG,"[onConnected] "+isConnected);
}
}
█ demo運行:
-
● 我們運行下,看看執行的過程:
MyReceiver和PushMessageReceiver都執行了【和極光服務器的連接狀態】的推送
05-26 10:19:17.700 4763-4763/ E/JIGUANG-Example: [ExampleApplication] onCreate
05-26 10:19:18.205 4763-4901/ E/PushMessageReceiver: [onNotificationSettingsCheck] isOn:true,source:0
05-26 10:19:18.234 4763-4763/ E/JIGUANG-Example: [MyReceiver] onReceive - cn.jpush.android.intent.CONNECTION, extras: key:cn.jpush.android.CONNECTION_CHANGE, value:true
05-26 10:19:18.234 4763-4763/ E/JIGUANG-Example: [MyReceiver]cn.jpush.android.intent.CONNECTION connected state change to true
05-26 10:19:18.235 4763-4901/ E/PushMessageReceiver: [onConnected] true
● 發送一條【自定義消息】-再發送一條【發送通知】-點擊通知欄的【發送通知】:
MyReceiver沒有收到消息,PushMessageReceiver收到消息,因此,我們推送可以直接使用PushMessageReceiver,並將MyReceiver去掉
05-26 10:25:00.751 4763-4901/ E/PushMessageReceiver: [onMessage] CustomMessage{messageId='47287858038278660', extra='', message='已經收到自定義消息', contentType='', title='', senderId='012345678901234567890123', appId='com.xxx.xxx'}
05-26 10:25:37.193 4763-4901/ E/PushMessageReceiver: [onNotifyMessageArrived] NotificationMessage{notificationId=536806284, msgId='47287858037918248', appkey='012345678901234567890123', notificationContent='點開我有驚喜', notificationAlertType=7, notificationTitle='今天是25號', notificationSmallIcon='', notificationLargeIcon='', notificationExtras='{}', notificationStyle=0, notificationBuilderId=0, notificationBigText='', notificationBigPicPath='', notificationInbox='', notificationPriority=0, notificationCategory='', developerArg0='', platform=0, notificationChannelId='', displayForeground='', notificationType=0}
05-26 10:26:31.569 4763-4763/ E/PushMessageReceiver: [onNotifyMessageOpened] NotificationMessage{notificationId=536806284, msgId='47287858037918248', appkey='012345678901234567890123', notificationContent='點開我有驚喜', notificationAlertType=7, notificationTitle='今天是25號', notificationSmallIcon='', notificationLargeIcon='', notificationExtras='{}', notificationStyle=0, notificationBuilderId=0, notificationBigText='', notificationBigPicPath='', notificationInbox='', notificationPriority=0, notificationCategory='', developerArg0='', platform=0, notificationChannelId='', displayForeground='', notificationType=0}
● 接下來刪除MyReceiver.java,在運行下demo,看是否可以收到推送:
刪除MyReceiver.java後,android會自動將AndroidManifest.xml中的相關信息刪除。並發現推送接收正常,說明確實可以直接棄用MyReceiver.java。
● 爲什麼MyReceiver.java收不到推送?
在新的SDK中,是優先PushMessageReceiver接收,之後是否有調用super,確定是否繼續廣播到舊版本Receiver
如果需要在舊版本的Receiver接收cn.jpush.android.intent.MESSAGE_RECEIVED廣播
可以不重寫此方法,或者重寫此方法且調用super.onMessage
如果重寫此方法,沒有調用super,則不會發送廣播到舊版本Receiver
█ 推送的 jcenter 自動集成方法:
-
● 注意事項:
從JPush3.0.7開始,需要配置繼承JPushMessageReceiver的廣播,原來如果配了MyReceiver現在可以棄用
從JPush3.2.2開始,需要 JCore2.1.1 及以上的 版本,升級 SDK 的時候請將 JCore 一起升級。
從JCore2.0.0開始,需要額外在 Androidmanifest 中配置一個繼承極光JCommonService的Service,可以在更多手機平臺上獲得更穩定的推送通道的支持。(JCore1.x版本不需要)
需要留意iOS證書是否到期,否則將導致無法接收到推送
jcenter 自動集成時,不需要在jniLibs中添加 jar 和 so;jar手動集成時,需要在jniLibs中添加 jar 和 so,還要在AndroidManifest.xml 中添加比前者更多的JPush SDK 相關的配置。
對於每個App,月推送去重設備數小於5萬的情況免費。
● 此時使用的版本:
implementation ‘cn.jiguang.sdk:jpush:3.6.0’ // 此處以JPush 3.6.0 版本爲例。
implementation ‘cn.jiguang.sdk:jcore:2.3.4’ // 此處以JCore 2.3.4 版本爲例。
● demo使用jar手動集成,未使用 jcenter 自動集成,這裏也使用了 jcenter 自動集成:
傳送門:含jar手動集成和 jcenter 自動集成的demo,
用戶只需要修改下build.gradle中的applicationId和AppKey即可,親測,可用,操作步驟可以直接參考官網:極光推送 - Android SDK 集成指南 - 極光文檔
█ 推送的消息解析:
-
● 極光推送 - Push API v3 - 推送對象 - 極光文檔:
● notification:通知
{
"notification" : {
"android" : {
"alert" : "hello, JPush!", // 通知內容
"title" : "JPush test", // 通知標題
"builder_id" : 3, // 通知欄樣式 ID
"style":1 // 1,2,3 // 通知欄樣式類型
"alert_type":1 // -1 ~ 7 // 通知提醒方式
"big_text":"big text content",// 大文本通知欄樣式
"inbox":JSONObject,// 文本條目通知欄樣式
"big_pic_path":"picture url",// 大圖片通知欄樣式
"priority":0, // -2~2 // 通知欄展示優先級
"category":"category str", // 通知欄條目過濾或排序
"large_icon": "http://www.jiguang.cn/largeIcon.jpg",// 通知欄大圖標
"intent": {// 指定跳轉頁面
"url": "intent:#Intent;component=com.jiguang.push/com.example.jpushdemo.SettingActivity;end",
},
"extras" : {// 擴展字段
"news_id" : 134,
"my_key" : "a value"
}
}
}
}
● message:自定義消息
"message": {
"msg_content": "Hi,JPush",// 消息內容本身
"content_type": "text",// 消息內容類型
"title": "msg",// 消息標題
"extras": {// JSON 格式的可選參數
"key": "value"
}
},
● MyReceiver接收的方式(以下部分沒有經過驗證,僅供參考):
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
Log.e(TAG, "[MyReceiver] 接收到推送下來的自定義消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
// ######################【自定義消息】推送處理######################
String title= bundle.getString(JPushInterface.EXTRA_TITLE);//消息的標題
String message= bundle.getString(JPushInterface.EXTRA_MESSAGE);// 消息內容本身
String extras= bundle.getString(JPushInterface.EXTRA_EXTRA);// 擴展字段
if (!TextUtils.isEmpty(extras)) {
try {
Msg msg = new Gson().fromJson(extras, Msg.class);
.......
.......
} catch (Exception e) {
e.printStackTrace();
}
}
}else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
Log.e(TAG, "[MyReceiver] 用戶點擊打開了通知");
// ######################【發送通知】通知打開處理######################
String title= bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);// 通知標題
String alert= bundle.getString(JPushInterface.EXTRA_ALERT);// 通知內容
String extras= bundle.getString(JPushInterface.EXTRA_EXTRA);// 擴展字段
if (!TextUtils.isEmpty(extras)) {
try {
Msg msg = new Gson().fromJson(extras, Msg.class);
.......
.......
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
● JPushMessageReceiver接收的方式(以下部分沒有經過驗證,僅供參考):
public class PushMessageReceiver extends JPushMessageReceiver {
private static final String TAG = "PushMessageReceiver";
// ######################【自定義消息】推送處理######################
@Override
public void onMessage(Context context, CustomMessage customMessage) {
Log.e(TAG, "[onMessage] " + customMessage);
String title= customMessage.title;//消息的標題
String message= customMessage.message;// 消息內容本身
String extras= customMessage.extra;// 擴展字段
if (!TextUtils.isEmpty(extras)) {
try {
Msg msg = new Gson().fromJson(extras, Msg.class);
.......
.......
} catch (Exception e) {
e.printStackTrace();
}
}
}
// ######################【發送通知】通知打開處理######################
@Override
public void onNotifyMessageOpened(Context context, NotificationMessage message) {
Log.e(TAG, "[onNotifyMessageOpened] " + message);
String title= message.notificationTitle;// 通知標題
String alert= message.notificationContent;// 通知內容
String extras= message.notificationExtras;// 擴展字段
if (!TextUtils.isEmpty(extras)) {
try {
Msg msg = new Gson().fromJson(extras, Msg.class);
.......
.......
} catch (Exception e) {
e.printStackTrace();
}
}
}
// ######################【發送通知】推送處理######################
@Override
public void onNotifyMessageArrived(Context context, NotificationMessage message) {
Log.e(TAG, "[onNotifyMessageArrived] " + message);
}
}
█ 相關資料:
-
● 1.阿里雲移動研發平臺EMAS控制檯、開發文檔、跟着Demo快速體驗移動推送
● 2.2018-04-03 Android極光推送使用方法大全(升級JCore爲2.0版本) - Wang_Mr - 簡書
● 3.2019-06-25 極光推送第二篇:消息接收 - Small_Cake -
簡書
● 4.2017-08-01 極光推送api_移動開發_fishmai的專欄-CSDN博客
轉載請註明出處:
https://blog.csdn.net/ljb568838953/article/details/106396266