做手機控車項目,需求是車在遭受非法侵入的時候要及時報警,之前是用短信的方式,一開始量少還可以,隨着用戶越來越多,短信的開銷越來越大,決定做成推送方式,這就要求客戶一定能夠收到推送,無論後臺進程是否被殺死.
首先登陸阿里雲官方平臺,創建應用 阿里雲創建應用
然後就是下載各種包配置應用,有maven庫快速集成方式,但我不知道爲什麼下載不下來,所以還是選擇了手動配置,以下是用到的包
配置appkey和appsecret(創建應用時候生成的)
<application android:name="*****">
<meta-data android:name="com.alibaba.app.appkey" android:value="*****"/> <!-- 請填寫你自己的- appKey -->
<meta-data android:name="com.alibaba.app.appsecret" android:value="****"/> <!-- 請填寫你自己的appSecret -->
</application>
清單文件裏增加權限和註冊service和receiver
手動創建消息接收Receiver,繼承自com.alibaba.sdk.android.push.MessageReceiver,並在對應回調中添加業務處理邏輯
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
<!-- 消息接收監聽器 (用戶可自主擴展) -->
<receiver
android:name=".MyMessageReceiver"
android:exported="false"> <!-- 爲保證receiver安全,建議設置不可導出,如需對其他應用開放可通過android:permission進行限制 -->
<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>
然後官方文檔裏有這樣一句提示
如果是從V2.3.7及以下版本升級到V3.0.0及以上版本的用戶,需將<action android:name="org.agoo.android.intent.action.RECEIVE" />
改爲<action android:name="com.alibaba.sdk.android.push.RECEIVE" />
,否則會接收不到推送。
雖然我不是這樣的用戶,但還是做了修改
然後再application裏初始化推送通道(此處考慮了8.0以上限制推送的情況:即定義了一個通知渠道的id)
/**
* 初始化雲推送通道
* @param applicationContext
*/
private void initCloudChannel(Context applicationContext) {
if (android.os.Build.VERSION.SDK_INT >= android.os.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("測試通知組");
// // 是否繞過請勿打擾模式
mChannel.canBypassDnd();
// // 設置繞過請勿打擾模式
mChannel.setBypassDnd(true);
// // 桌面Launcher的消息角標
mChannel.canShowBadge();
// // 設置顯示桌面Launcher的消息角標
mChannel.setShowBadge(true);
// // 設置通知出現時聲音,默認通知是有聲音的
// mChannel.setSound(null, null);
// // 設置通知出現時的閃燈(如果 android 設備支持的話)
// mChannel.enableLights(true);
// mChannel.setLightColor(Color.RED);
// // 設置通知出現時的震動(如果 android 設備支持的話)
// mChannel.enableVibration(true);
// 配置通知渠道的屬性
mChannel.setDescription(description);
// 設置通知出現時的閃燈(如果 android 設備支持的話)
mChannel.enableLights(true);
mChannel.setLightColor(Color.RED);
// 設置通知出現時的震動(如果 android 設備支持的話)
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
//最後在notificationmanager中創建該通知渠道
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(mChannel);
}
}
// AdvancedCustomPushNotification notification = new AdvancedCustomPushNotification(R.layout.notitfication_layout, R.id.m_icon, R.id.m_title, R.id.m_text);
// notification.setServerOptionFirst(true);
// notification.setBuildWhenAppInForeground(true);
// notification.setRemindType(BasicCustomPushNotification.REMIND_TYPE_VIBRATE_AND_SOUND);
// boolean res = CustomNotificationBuilder.getInstance().setCustomNotification(2, notification);
PushServiceFactory.init(applicationContext);
pushService = PushServiceFactory.getCloudPushService();
pushService.register(applicationContext, new CommonCallback() {
@Override
public void onSuccess(String response) {
Log.d("MyMessageReceiver", "init cloudchannel success"+response+ pushService.getDeviceId());
}
@Override
public void onFailed(String errorCode, String errorMessage) {
Log.d("MyMessageReceiver", "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage);
}
});
}
至此,就可以在控制檯測試阿里雲推送了
接下來纔是重點
以上操作只能保證APP開啓或者進程在後臺運行的情況下才能收到推送(有時候後臺運行也收不到),在後臺進程被殺死的情況下,是不能收到推送的,好在阿里雲提供的有移動推送輔助通道,這個東西,個人理解就是阿里雲與各個手機廠商的合作,需要去各個手機廠商的開發平臺去申請,申請成功就相當於借用廠商通道向廠商自己製造的手機發送通知,這樣就不再受進程限制
那就要一個一個來:輔助通道配置
一:華爲
首先在華爲開發者聯盟註冊APP,得到APPID和APPsecret,並開啓push功能 開啓push服務
下載輔助通道擴展包 阿里雲maven庫地址,可搜索並下載擴展包 這裏其實可以直接連接maven庫,很不幸,我還是不能從maven中取包,所以只能手動集成
另外阿里雲官方文檔裏添加的輔助推送擴展包依賴是3.0.10版本,但maven裏最新的只有3.0.9版本
這裏很矛盾,暫且不問(至於他說的OPPO,vivo需使用3.0.10版本,鑑於本人在寫這篇文章時只做了華爲,所以先擱置,車到山前必有路,做到了再說)
項目裏添加華爲推送sdk依賴:
dependencies {
......
compile 'com.aliyun.ams:huawei-push:2.6.3.305'
compile 'com.aliyun.ams:huawei-push-base:2.6.3.305'
}
同時在AndroidManifest文件中添加如下配置:
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="華爲開放平臺申請的ID信息(appid)" />
在application.onCreate()方法中初始化廠商通道. 注意:輔助通道註冊務必在Application中執行且放在推送SDK初始化代碼之後,否則可能導致輔助通道註冊失敗
// 註冊方法會自動判斷是否支持小米系統推送,如不支持會跳過註冊。
MiPushRegister.register(applicationContext, "小米AppID", "小米AppKey");
// 註冊方法會自動判斷是否支持華爲系統推送,如不支持會跳過註冊。
HuaWeiRegister.register(application);
//GCM/FCM輔助通道註冊
GcmRegister.register(this, sendId, applicationId); //sendId/applicationId爲步驟獲得的參數
// OPPO通道註冊
OppoRegister.register(applicationContext, appKey, appSecret); // appKey/appSecret在OPPO開發者平臺獲取
// 魅族通道註冊
MeizuRegister.register(applicationContext, "appId", "appkey"); // appId/appkey在魅族開發者平臺獲取
// VIVO通道註冊
VivoRegister.register(applicationContext);
可打印日誌查看通道初始化是否成功
如不成功,檢查是否在華爲控制檯配置SHA256指紋證書,目前華爲需要配置 生成並配置指紋證書
這裏我一開始初始化失敗了,配置指紋證書之後就成功了
通過輔助通道(廠商通道)送達的通知,要定義一個activity去接收數據:官方文檔如下:
- 服務端指定輔助彈窗通道推送時,一定要指定通知點擊後要打開的Activity,該Activity需繼承自抽象類
AndroidPopupActivity
(MiPushSystemNotificationActivity
已廢棄,小米、華爲、OPPO等廠商通道彈窗統一繼承AndroidPopupActivity
),否則無法獲取到通知的相關信息,並且會影響通知到達率的統計; AndroidPopupActivity
中提供抽象方法onSysNoticeOpened()
,實現該方法後可獲取到輔助彈窗通知的標題
、內容
和額外參數
,在通知點擊時觸發,原本的通知回調onNotification()
和onNotificationOpened()
不適用於輔助彈窗;-
指定打開的託管彈窗Activity在AndroidManifest.xml中註冊時需要聲明屬性:
android:exported=true
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);
}
/**
* 實現通知打開回調方法,獲取通知相關信息
* @param title 標題
* @param summary 內容
* @param extMap 額外參數
*/
@Override
protected void onSysNoticeOpened(String title, String summary, Map<String, String> extMap) {
Log.d("OnMiPushSysNoticeOpened, title: " + title + ", content: " + summary + ", extMap: " + extMap);
}
}
服務端在推送時,需自己配置好appkey和appsecret,還要置頂輔助彈框對應的activity
在控制檯的表現就是
至此,華爲手機上的app無論後臺進程存在與否,都能收到推送
其他手機廠商也差不多都是這樣的流程,等我做完了,哪個有特別需要注意的地方,再來更新