Android 集成阿里移動推送

1.android的推送一直飽受詬病,最近項目中需要用到推送劣摇。本來用的是極光推送,但是應用一旦被殺死推送便收不到。我跟boss說這是android的問題,不能做到ios那樣百分百推送,但是boss說你看人家誰誰的應用我清理掉后臺推送怎么還可以收到的畴。最后經(jīng)過網(wǎng)上的一通搜,查到了輔助通道推送。

2.什么是輔助通道推送,即集成品牌機的官方推送(華為尝胆、小米丧裁、OPPO)這樣如果你的應用在這些手機上即使殺死APP照樣可以收到通知,但是如果沒有集成輔助通道推送那收到通知只能隨緣了。

3.我集成了阿里的移動推送這里記錄一下含衔。畢竟不是專業(yè)做推送的就在我集成的當天,阿里的移動推送居然出問題了,IOS的通知延時高達3小時上新聞了煎娇。不管了android沒受影響,關(guān)鍵是boss的手機是華為手機必須保證boss是手機能收到推送哈哈。

4.貼上阿里移動推送的官方鏈接:https://help.aliyun.com/document_detail/51056.html?spm=a2c4g.11174283.3.4.52eb6d16SpqQmM

5.建議使用maven快速集成簡單方便贪染。

(1).在Project根目錄下build.gradle文件中配置maven庫URL:

allprojects {
repositories {
jcenter()
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}

(2).在對應的module下的build.gradle文件中添加對應依賴缓呛。

android {
......
defaultConfig {
applicationId "com.xxx.xxx" //包名
......
ndk {
//選擇要添加的對應cpu類型的.so庫。
abiFilters 'armeabi', 'x86'
}
......
}
......
}
dependencies {
......
implementation 'com.aliyun.ams:alicloud-android-push:3.1.4'
......
}

注 : 如果在添加以上 abiFilter 配置之后android Studio出現(xiàn)以下提示(我是沒有遇到):

NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin.
則在 Project 根目錄的gradle.properties文件中添加:

android.useDeprecatedNdk=true

(3).在AndroidManifest文件中設置appKey杭隙,appSecret(注:這里有個坑在粘貼appsecret的時候多個空格注意要刪掉!!!!):

<application android:name="*****">
<meta-data android:name="com.alibaba.app.appkey" android:value="*****"/>
<meta-data android:name="com.alibaba.app.appsecret" android:value="****"/>
</application>

(4).創(chuàng)建消息接收Receiver哟绊,繼承自com.alibaba.sdk.android.push.MessageReceiver,并在對應回調(diào)中添加業(yè)務處理邏輯,可參考以下代碼:

public class MyMessageReceiver extends MessageReceiver {
// 消息接收部分的LOG_TAG
public static final String REC_TAG = "receiver";
@Override
public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) {
// TODO 處理推送通知
Log.e("MyMessageReceiver", "Receive notification, title: " + title + ", summary: " + summary + ", extraMap: " + extraMap);
}
@Override
public void onMessage(Context context, CPushMessage cPushMessage) {
Log.e("MyMessageReceiver", "onMessage, messageId: " + cPushMessage.getMessageId() + ", title: " + cPushMessage.getTitle() + ", content:" + cPushMessage.getContent());
}
@Override
public void onNotificationOpened(Context context, String title, String summary, String extraMap) {
Log.e("MyMessageReceiver", "onNotificationOpened, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
}
@Override
protected void onNotificationClickedWithNoAction(Context context, String title, String summary, String extraMap) {
Log.e("MyMessageReceiver", "onNotificationClickedWithNoAction, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
}
@Override
protected void onNotificationReceivedInApp(Context context, String title, String summary, Map<String, String> extraMap, int openType, String openActivity, String openUrl) {
Log.e("MyMessageReceiver", "onNotificationReceivedInApp, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap + ", openType:" + openType + ", openActivity:" + openActivity + ", openUrl:" + openUrl);
}
@Override
protected void onNotificationRemoved(Context context, String messageId) {
Log.e("MyMessageReceiver", "onNotificationRemoved");
}
}
將該receiver添加到AndroidManifest.xml中

<receiver
android:name=".MyMessageReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.RECEIVE" />
</intent-filter>
</receiver>

(4).混淆配置

-keepclasseswithmembernames class ** {
native <methods>;
}
-keepattributes Signature
-keep class sun.misc.Unsafe { ; }
-keep class com.taobao.
* {;}
-keep class com.alibaba.
* {;}
-keep class com.alipay.
* {;}
-keep class com.ut.
* {;}
-keep class com.ta.
* {;}
-keep class anet.
{;}
-keep class anetwork.{;}
-keep class org.android.spdy.
{;}
-keep class org.android.agoo.{;}
-keep class android.os.
{;}
-dontwarn com.taobao.**
-dontwarn com.alibaba.**
-dontwarn com.alipay.**
-dontwarn anet.**
-dontwarn org.android.spdy.**
-dontwarn org.android.agoo.**
-dontwarn anetwork.**
-dontwarn com.ut.**
-dontwarn com.ta.**

(5).初始化阿里推送

首先通過PushServiceFactory獲取到CloudPushService痰憎,然后調(diào)用register()初始化并注冊云推送通道票髓,并確保Application上下文中進行初始化工作。
請參照以下代碼段進行初始化
import android.app.Application;
import android.content.Context;
import android.util.Log;
import com.alibaba.sdk.android.push.CloudPushService;
import com.alibaba.sdk.android.push.CommonCallback;
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
public class MainApplication extends Application {
private static final String TAG = "Init";
@Override
public void onCreate() {
super.onCreate();
initCloudChannel(this);
}
/**
* 初始化云推送通道
* @param applicationContext
*/
private void initCloudChannel(Context applicationContext) {
PushServiceFactory.init(applicationContext);
CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.register(applicationContext, new CommonCallback() {
@Override
public void onSuccess(String response) {
Log.d(TAG, "init cloudchannel success");
}
@Override
public void onFailed(String errorCode, String errorMessage) {
Log.d(TAG, "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage);
}
});
}
}
【注意】:

  • 移動推送的初始化必須在Application中铣耘,不能放到Activity中執(zhí)行洽沟。移動推送在初始化過程中將啟動后臺進程channel,必須保證應用進程和channel進程都執(zhí)行到推送初始化代碼蜗细。
  • 如果設備成功注冊裆操,將回調(diào)callback.onSuccess()方法。
  • 但如果注冊服務器連接失敗,則調(diào)用callback.onFailed方法踪区,并且自動進行重新注冊昆烁,直到onSuccess為止。(重試規(guī)則會由網(wǎng)絡切換等時間自動觸發(fā)朽缴。)
  • 請在網(wǎng)絡通暢的情況下進行相關(guān)的初始化調(diào)試善玫,如果網(wǎng)絡不通,或者App信息配置錯誤密强,在onFailed方法中茅郎,會有相應的錯誤碼返回,可參考錯誤處理或渤。

啟動正常確認方法:

  • 回調(diào)方法callback.onSuccess()被調(diào)用系冗。以上文接入代碼為例,logcat將會打印以下日志:
  1. 11-24 12:55:51.096 15235-15535/com.alibaba.xxxx D/YourApp﹕ init cloudchannel success
  • 確認cloudchannel初始化正常薪鹦,在logcat日志中:輸入awcn關(guān)鍵字:
  1. 11-24 12:53:51.036 15235-15556/com.alibaba.xxxx E/awcn﹕ |[seq:AWCN1_1] AUTH httpStatusCode: 200
  2. 11-24 12:53:51.036 15235-15556/com.alibaba.xxxx E/awcn﹕ |[seq:AWCN1_1] status:AUTH_SUCC
  • 確認DeviceId獲取正常:在初始化成功后使用 cloudPushService.getDeviceId() 獲取deviceId掌敬,應該能夠成功獲取。

  • 如果集成移動推送的過程中遇到了utdid沖突池磁,可參考:阿里云-移動云產(chǎn)品SDK UTDID沖突解決方案
    (6).Android8.0及以上NotificationChannel機制
    在客戶端創(chuàng)建自己的NotificationChannel奔害,可參考下面代碼

具體調(diào)用位置為:Application的onCreate,云推初始化前后都可以地熄,可參考 Demo

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 通知渠道的id
String id = "1";
// 用戶可以看到的通知渠道的名字.
CharSequence name = "notification channel";
// 用戶可以看到的通知渠道的描述
String description = "notification description";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// 配置通知渠道的屬性
mChannel.setDescription(description);
// 設置通知出現(xiàn)時的閃燈(如果 android 設備支持的話)
mChannel.enableLights(true);
mChannel.setLightColor(Color.RED);
// 設置通知出現(xiàn)時的震動(如果 android 設備支持的話)
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
//最后在notificationmanager中創(chuàng)建該通知渠道
mNotificationManager.createNotificationChannel(mChannel);
}

(7).集成輔助通道推送华临。

(1).目前阿里只有華為、小米端考、OPPO雅潭、谷歌上各自的開放平臺開通推送服務配置到阿里的控制臺。

輔助通道1.png

(2).添加輔助通道依賴却特。

dependencies {
compile 'com.aliyun.ams:alicloud-android-third-push:3.0.6@aar'
}
(3).如果集成了谷歌商店的推送的話需要額外的配置一下
dependencies {
......
compile ('com.google.firebase:firebase-messaging:9.6.1')
}
同時在AndroidManifest文件中添加如下配置:

<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.taobao.taobao" />
</intent-filter>
</receiver>
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
android:exported="false" />
<service
android:name="com.alibaba.sdk.android.push.AgooFirebaseInstanceIDService"
android:exported="true" >
<intent-filter android:priority="-500" >
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service
android:name="com.alibaba.sdk.android.push.AgooFirebaseMessagingService"
android:exported="true" >
<intent-filter android:priority="-500" >
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>

(4).混淆配置扶供。

小米通道

-keep class com.xiaomi.** {;}
-dontwarn com.xiaomi.
*

華為通道

-keep class com.huawei.** {;}
-dontwarn com.huawei.
*

GCM/FCM通道

-keep class com.google.firebase.{;}
-dontwarn com.google.firebase.
*

OPPO通道

-keep public class * extends android.app.Service

(5).初始化輔助通道。

將以下代碼加入你application.onCreate()方法中初始通道裂明。注意:輔助通道注冊務必在Application中執(zhí)行且放在推送SDK初始化代碼之后椿浓,否則可能導致輔助通道注冊失敗

// 注冊方法會自動判斷是否支持小米系統(tǒng)推送,如不支持會跳過注冊闽晦。
MiPushRegister.register(applicationContext, "小米AppID", "小米AppKey");
// 注冊方法會自動判斷是否支持華為系統(tǒng)推送轰绵,如不支持會跳過注冊。
HuaWeiRegister.register(applicationContext);
//GCM/FCM輔助通道注冊
GcmRegister.register(this, sendId, applicationId); //sendId/applicationId為步驟獲得的參數(shù)
// OPPO通道注冊
OppoRegister.register(applicationContext, appKey, appSecret); // appKey/appSecret在OPPO通道開發(fā)者平臺獲
(6).用指定的機型查看log是否集成成功尼荆。
華為通道初始化成功,可以看到以下日志:

11-11 22:21:33.671 30248-30324/com.xxx E/MPS:HuaWeiRegister: HuaWeiRegister checkDevice flag=true //確認是華為的手機
11-11 22:21:33.674 30248-30324/com.xxx E/MPS:HuaWeiRegister﹕ Register huawei push............ //開始注冊華為手機
11-11 22:21:33.714 29643-30328/com.xxx E/MPS:HuaWeiRegister﹕ huawei register success唧垦,token = 08657430243125472000000411000001
小米通道初始化成功捅儒,可以看到以下日志:

12-09 22:20:39.710 19566-19566/com.xxx E/MPS:MiPushRegister: MiPushRegister checkDevice flag=true //確認是小米的手機
12-09 22:20:39.712 19566-19566/com.xxx E/MPS:MiPushRegister: Register mipush. //開始注冊小米
12-09 22:20:40.596 19566-19733/com.xxx E/MPS:MiPushRegister: XiaoMi register success. //小米注冊成功 regid=d//igwEhgBGCI2TG6lWqlCesc0I6xE1wUhNCBXQ8uNOi/dDZioYXVysbrVrvRmyEVPn9nWz92D28IzYbA1RzoGDyTzYZwXKfBHEQkrey4G8=
GCM/FCM通道初始化成功,可以看到以下日志:

05-19 19:18:44.530 19153-19177/com.xxx D/MPS:GcmRegister: token from register: eWIXLYCNP0Q:APA91bFUAgxj6XYf5okyoCBnRPw1UwITndzXrvPDgbdI2N44PYm17hFEBiNXNQJrJ8bOG_xjw3c3UPDAhzNMTLNjlAKcjUanKyLA6E3k4wEmgZuhgUT02UMmMvH2LVA1L2Z4-l-cT_Ug
收到小米通道下行的消息:(需要將sdk日志等級設置到DEBUG)

12-09 22:24:34.065 19566-25042/com.xxx D/MPS:MiPushReceiver: onReceiveMessage,msg=[{"f":262,"b":"{"content"\ ... ... ,"i":"f__-rnje3_OH74gE|VG0g3kwMnGADAGrXZku1FFW5"}]
收到GCM/FCM通道下發(fā)的消息:

05-19 19:20:04.900 19153-20391/com.alibaba.push2 D/MPS:GcmRegister: onReceiveMessage payload msg:[.

(7).該功能的使用需要接入推送輔助通道,確保使用最新的輔助通道擴展包巧还,具體參考上文鞭莽;

輔助彈窗送達的通知展示效果,和普通通知相同麸祷;
服務端指定輔助彈窗通道推送時澎怒,一定要指定通知點擊后要打開的Activity,該Activity需繼承自抽象類AndroidPopupActivity(MiPushSystemNotificationActivity已廢棄阶牍,小米彈窗喷面、華為彈窗、OPPO彈窗統(tǒng)一繼承AndroidPopupActivity)走孽,否則無法獲取到通知的相關(guān)信息惧辈,并且會影響通知到達率的統(tǒng)計;
AndroidPopupActivity中提供抽象方法onSysNoticeOpened()磕瓷,實現(xiàn)該方法后可獲取到輔助彈窗通知的標題盒齿、內(nèi)容和額外參數(shù),在通知點擊時觸發(fā)困食,原本的通知回調(diào)onNotification()和onNotificationOpened()不適用于輔助彈窗边翁;
指定打開的托管彈窗Activity在AndroidManifest.xml中注冊時需要聲明屬性:android:exported=true
注:AndroidPopupActivity 適合作為中間件,因為它繼承自Activity擴展性差。點擊彈窗回調(diào)onSysNoticeOpened()方法!!!
import com.alibaba.sdk.android.push.AndroidPopupActivity;
public class PopupPushActivity extends AndroidPopupActivity {
static final String TAG = "PopupPushActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* 實現(xiàn)通知打開回調(diào)方法硕盹,獲取通知相關(guān)信息
* @param title 標題
* @param summary 內(nèi)容
* @param extMap 額外參數(shù)
*/
@Override
protected void onSysNoticeOpened(String title, String summary, Map<String, String> extMap) {
Log.d("OnMiPushSysNoticeOpened, title: " + title + ", content: " + summary + ", extMap: " + extMap);
}
}

另外對通知的標題長度限制是16個字符,但是我試了超過10個就不行了,不知道是不是服務端哪里設置的有問題暫時沒解決符匾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市莱睁,隨后出現(xiàn)的幾起案子待讳,更是在濱河造成了極大的恐慌,老刑警劉巖仰剿,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件创淡,死亡現(xiàn)場離奇詭異,居然都是意外死亡南吮,警方通過查閱死者的電腦和手機琳彩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來部凑,“玉大人露乏,你說我怎么就攤上這事⊥垦” “怎么了瘟仿?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長比勉。 經(jīng)常有香客問我劳较,道長驹止,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任观蜗,我火速辦了婚禮臊恋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘墓捻。我一直安慰自己抖仅,他們只是感情好,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布砖第。 她就那樣靜靜地躺著撤卢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厂画。 梳的紋絲不亂的頭發(fā)上凸丸,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機與錄音袱院,去河邊找鬼屎慢。 笑死,一個胖子當著我的面吹牛忽洛,可吹牛的內(nèi)容都是我干的腻惠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼欲虚,長吁一口氣:“原來是場噩夢啊……” “哼集灌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起复哆,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤欣喧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后梯找,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唆阿,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年锈锤,在試婚紗的時候發(fā)現(xiàn)自己被綠了驯鳖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡久免,死狀恐怖浅辙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阎姥,我是刑警寧澤记舆,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站呼巴,受9級特大地震影響泽腮,放射性物質(zhì)發(fā)生泄漏泊愧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一盛正、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧屑埋,春花似錦豪筝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至团搞,卻和暖如春严望,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逻恐。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工像吻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人复隆。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓拨匆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親挽拂。 傳聞我的和親對象是個殘疾皇子惭每,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容