阿里雲移動推送學習筆記
第一步:項目build.gradle文件配置
buildscript {
repositories {
......
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
......
}
allprojects {
repositories {
......
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}
第二步:Module中build.gradle文件配置
defaultConfig {
applicationId "com.quanyou.daggertest"
......
ndk {
//選擇要添加的對應cpu類型的.so庫。
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
dependencies {
......
//aliyun推送
implementation 'com.aliyun.ams:alicloud-android-push:3.1.4@aar'
implementation 'com.aliyun.ams:alicloud-android-utdid:1.1.5.3'
implementation 'com.aliyun.ams:alicloud-android-ut:5.4.0'
implementation 'com.aliyun.ams:alicloud-android-utils:1.1.3'
implementation 'com.aliyun.ams:alicloud-android-beacon:1.0.1'
//移動推送輔助通道配置
implementation 'com.aliyun.ams:alicloud-android-third-push:3.0.3@aar'
}
第三步:build工程,然後到阿里雲官網控制檯添加應用,然後記錄appKey 和appSecret
第四步:AndroidManifest文件配置
<!-- 阿里雲推送相關權限 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<application
android:name=".base.MyApplication"
......>
<meta-data android:name="com.alibaba.app.appkey" android:value="*****"/> <!-- 請填寫你自己的- appKey -->
<meta-data android:name="com.alibaba.app.appsecret" android:value="****"/> <!-- 請填寫你自己的appSecret -->
......
</application>
第五步:初始化阿里雲推送
在自定義Application中聲明如下方法並在onCreate方法中調用
fun initCloudChannel(applicationContext: Application) {
PushServiceFactory.init(applicationContext)
val pushService = PushServiceFactory.getCloudPushService()
pushService.register(applicationContext, object : CommonCallback {
override fun onSuccess(response: String) {
//獲取設備號
val deviceId = pushService.deviceId
LogUtils.e("MyApplication", "init cloudchannel success " + deviceId)
}
override fun onFailed(errorCode: String, errorMessage: String) {
val packageName = applicationContext.getApplicationInfo().packageName
LogUtils.e("MyApplication", "當前packageName:$packageName -- init cloudchannel failed -- errorcode:$errorCode -- errorMessage:$errorMessage")
}
})
//android 8.0支持
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val mNotificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
// 通知渠道的id
val id = "1"
// 用戶可以看到的通知渠道的名字.
val name = "notification channel"
// 用戶可以看到的通知渠道的描述
val description = "notification description"
val importance = NotificationManager.IMPORTANCE_HIGH
val mChannel = NotificationChannel(id, name, importance)
// 配置通知渠道的屬性
mChannel.description = description
// 設置通知出現時的閃燈(如果 android 設備支持的話)
mChannel.enableLights(true)
mChannel.lightColor = Color.RED
// 設置通知出現時的震動(如果 android 設備支持的話)
mChannel.enableVibration(true)
mChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
//最後在notificationmanager中創建該通知渠道
mNotificationManager!!.createNotificationChannel(mChannel)
}
/*輔助通道設置*/
// 註冊方法會自動判斷是否支持小米系統推送,如不支持會跳過註冊。
MiPushRegister.register(applicationContext, "小米AppID", "小米AppKey");
// 註冊方法會自動判斷是否支持華爲系統推送,如不支持會跳過註冊。
HuaWeiRegister.register(applicationContext);
//GCM/FCM輔助通道註冊
GcmRegister.register(applicationContext, "sendId", applicationContext.applicationInfo.packageName); //sendId/applicationId爲步驟獲得的參數
// OPPO通道註冊
OppoRegister.register(applicationContext, "appKey", "appSecret"); // appKey/appSecret在OPPO通道開發者平臺獲取
}
第六步:自定義AliyunMessageIntentService服務
自定義AliyunMessageIntentService服務用於接收通知
/**
* Created by liyazhou on 17/8/22.
* 爲避免推送廣播被系統攔截的小概率事件,我們推薦用戶通過IntentService處理消息互調,接入步驟:
* 1. 創建IntentService並繼承AliyunMessageIntentService
* 2. 覆寫相關方法,並在Manifest的註冊該Service
* 3. 調用接口CloudPushService.setPushIntentService
* 詳細用戶可參考:https://help.aliyun.com/document_detail/30066.html#h2-2-messagereceiver-aliyunmessageintentservice
*/
class MyMessageIntentService : AliyunMessageIntentService() {
/**
* 推送通知的回調方法
*/
override fun onNotification(context: Context, title: String, summary: String, extraMap: Map<String, String>) {
LogUtils.e(REC_TAG, "收到一條推送通知 : $title, summary:$summary")
}
/**
* 推送消息的回調方法
*/
override fun onMessage(context: Context, cPushMessage: CPushMessage) {
LogUtils.e(REC_TAG, "收到一條推送消息 : " + cPushMessage.title + ", content:" + cPushMessage.content)
}
/**
* 從通知欄打開通知的擴展處理
*/
override fun onNotificationOpened(context: Context, title: String, summary: String, extraMap: String) {
LogUtils.e(REC_TAG, "onNotificationOpened : : $title : $summary : $extraMap")
}
/**
* 無動作通知點擊回調。當在後臺或阿里雲控制檯指定的通知動作爲無邏輯跳轉時,通知點擊回調爲onNotificationClickedWithNoAction而不是onNotificationOpened
*/
override fun onNotificationClickedWithNoAction(context: Context, title: String, summary: String, extraMap: String) {
LogUtils.e(REC_TAG, "onNotificationClickedWithNoAction : : $title : $summary : $extraMap")
}
/**
* 通知刪除回調
*/
override fun onNotificationRemoved(context: Context, messageId: String) {
LogUtils.e(REC_TAG, "onNotificationRemoved : $messageId")
}
/**
* 應用處於前臺時通知到達回調。注意:該方法僅對自定義樣式通知有效,相關詳情請參考https://help.aliyun.com/document_detail/30066.html#h3-3-4-basiccustompushnotification-api
*/
override fun onNotificationReceivedInApp(context: Context, title: String, summary: String, extraMap: Map<String, String>, openType: Int, openActivity: String, openUrl: String) {
LogUtils.e(REC_TAG, "onNotificationReceivedInApp : : $title : $summary $extraMap : $openType : $openActivity : $openUrl")
}
companion object {
private val TAG = "MyMessageIntentService"
}
}
,並在AndroidManifest文件中註冊
<service
android:name=".service.MyMessageIntentService"
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>
</service>
附:通知設置工具類
object SettingNoticeUtils {
/**
* 獲取推送服務
*/
fun getCloudPushService(): CloudPushService {
return PushServiceFactory.getCloudPushService()
}
private fun getIdentifier(context: Context, resType: String, resName: String): Int {
val identifier = context.resources.getIdentifier(resName, resType, context.packageName)
return identifier
}
private fun getRawIdentifier(context: Context, resName: String): Int {
val identifier = getIdentifier(context, "raw", resName)
return identifier
}
private fun getDrawableIdentifier(context: Context, resName: String): Int {
val identifier = getIdentifier(context, "drawable", resName)
return identifier
}
private fun getRawPath(context: Context, identifier: Int): String {
val packageName = context.packageName
val path = "android.resource://$packageName/$identifier"
return path
}
fun drawable2Bitmap(drawable: Drawable): Bitmap? {
return when (drawable) {
is BitmapDrawable -> drawable.bitmap
is NinePatchDrawable -> {
val bitmap = Bitmap
.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
if (drawable.getOpacity() != PixelFormat.OPAQUE)
Bitmap.Config.ARGB_8888
else
Bitmap.Config.RGB_565)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight())
drawable.draw(canvas)
bitmap
}
else -> null
}
}
/**
* 設置通知聲音
*/
fun setNotifSound(path: String) {
getCloudPushService().setNotificationSoundFilePath(path)
}
fun setNotifSound(context: Context, resName: String) {
val identifier = getRawIdentifier(context, resName)
if (0 != identifier) {
val path = getRawPath(context, identifier)
getCloudPushService().setNotificationSoundFilePath(path)
} else {
LogUtils.e("SettingNoticeUtils", "未發現資源: $resName")
}
}
/**
* 設置通知圖片(大圖標)
*/
fun setNotifIcon(bitmap: Bitmap) {
getCloudPushService().setNotificationLargeIcon(bitmap)
}
fun setNotifIcon(context: Context, @DrawableRes drawableResId: Int) {
val bitmap = BitmapFactory.decodeResource(context.resources, drawableResId)
if (null != bitmap) {
getCloudPushService().setNotificationLargeIcon(bitmap)
} else {
LogUtils.e("SettingNoticeUtils", "圖片資源不存在: $drawableResId")
}
}
fun setNotifIcon(drawable: Drawable) {
val bitmap = drawable2Bitmap(drawable)
if (null != bitmap) {
getCloudPushService().setNotificationLargeIcon(bitmap)
} else {
LogUtils.e("SettingNoticeUtils", "圖片資源不存在")
}
}
fun setNotifIcon(context: Context, resName: String) {
val identifier = getDrawableIdentifier(context, resName)
if (0 != identifier) {
val drawable = context.resources.getDrawable(identifier)
val bitmap = drawable2Bitmap(drawable)
if (null != drawable && null != bitmap) {
getCloudPushService().setNotificationLargeIcon(bitmap)
} else {
LogUtils.e("SettingNoticeUtils", "圖片資源不存在: $resName")
}
} else {
LogUtils.e("SettingNoticeUtils", "圖片資源不存在: $resName")
}
}
/**
* 自定義狀態欄通知圖標(小圖標)
*/
fun setNotifSmallIcon(context: Context, resName: String) {
val identifier = getDrawableIdentifier(context, resName)
if (0 != identifier) {
getCloudPushService().setNotificationSmallIcon(identifier)
} else {
LogUtils.e("SettingNoticeUtils", "圖片資源不存在: $resName")
}
}
/**
* 設置基礎自定義樣式通知示例
* @param remindType 設置提醒方式(無提示,震動,聲音,震動和聲音),傳參如下值:
* @sample [com.alibaba.sdk.android.push.notification.BasicCustomPushNotification.REMIND_TYPE_SILENT]
* @sample [com.alibaba.sdk.android.push.notification.BasicCustomPushNotification.REMIND_TYPE_VIBRATE]
* @sample [com.alibaba.sdk.android.push.notification.BasicCustomPushNotification.REMIND_TYPE_SOUND]
* @sample [com.alibaba.sdk.android.push.notification.BasicCustomPushNotification.REMIND_TYPE_VIBRATE_AND_SOUND]
*/
fun setBasicCusNotif(drawableResId: Int,
remindType: Int,
notifiId: Int,
isBuildWhenAppInForeground: Boolean,
isServerOptionFirst: Boolean,
callback: Callback?) {
val notification = BasicCustomPushNotification()
//設置狀態欄圖標
notification.statusBarDrawable = drawableResId
//設置提醒方式爲聲音
notification.remindType = remindType
//設置當推送到達時如果應用處於前臺不創建通知
notification.isBuildWhenAppInForeground = isBuildWhenAppInForeground
//設置服務端配置優先
notification.isServerOptionFirst = isServerOptionFirst
//註冊該通知,並設置ID
val isSuccess = CustomNotificationBuilder.getInstance().setCustomNotification(notifiId, notification)
callback?.isSuccess(isSuccess)
}
fun setBasicCusNotif(drawableResId: Int,
remindType: Int,
notifiId: Int,
isBuildWhenAppInForeground: Boolean,
isServerOptionFirst: Boolean) {
setBasicCusNotif(drawableResId, remindType, notifiId, isBuildWhenAppInForeground, isServerOptionFirst, null)
}
/**
* 設置高級自定義樣式通知示例
* @param remindType 設置提醒方式(無提示,震動,聲音,震動和聲音),傳參如下值:
* @sample [com.alibaba.sdk.android.push.notification.BasicCustomPushNotification.REMIND_TYPE_SILENT]
* @sample [com.alibaba.sdk.android.push.notification.BasicCustomPushNotification.REMIND_TYPE_VIBRATE]
* @sample [com.alibaba.sdk.android.push.notification.BasicCustomPushNotification.REMIND_TYPE_SOUND]
* @sample [com.alibaba.sdk.android.push.notification.BasicCustomPushNotification.REMIND_TYPE_VIBRATE_AND_SOUND]
*/
fun setAdvCusNotf(@LayoutRes layoutResId: Int,
@DrawableRes iconResId: Int,
@IdRes titleIdRes: Int,
@IdRes contentIdRes: Int,
isBuildWhenAppInForeground: Boolean,
isServerOptionFirst: Boolean,
remindType: Int,
notifiId: Int,
callback: Callback?) {
//創建高級自定義樣式通知,設置佈局文件以及對應的控件ID
val notification = AdvancedCustomPushNotification(layoutResId, iconResId, titleIdRes, contentIdRes)
//設置服務端配置優先
notification.isServerOptionFirst = isServerOptionFirst
//設置提醒方式爲聲音
notification.remindType = remindType
//設置當推送到達時如果應用處於前臺不創建通知
notification.isBuildWhenAppInForeground = isBuildWhenAppInForeground
val isSuccess = CustomNotificationBuilder.getInstance().setCustomNotification(notifiId, notification)
callback?.isSuccess(isSuccess)
}
fun setAdvCusNotf(@LayoutRes layoutResId: Int,
@DrawableRes iconResId: Int,
@IdRes titleIdRes: Int,
@IdRes contentIdRes: Int,
isBuildWhenAppInForeground: Boolean,
isServerOptionFirst: Boolean,
remindType: Int,
notifiId: Int) {
SettingNoticeUtils.setAdvCusNotf(layoutResId, iconResId, titleIdRes, contentIdRes, isBuildWhenAppInForeground, isServerOptionFirst, remindType, notifiId)
}
/**
* 設置接收消息IntentService示例
* 1. 設置後,所有推送相關互調全部通過對應IntentService透出
*/
fun setIntentService(clazz: Class<AliyunMessageIntentService>) {
getCloudPushService().setPushIntentService(clazz)
}
/**
* 設置接收消息BroadcastReceiver示例
* 1. 系統默認通過廣播方式發送給對應BroadcastReceiver
* 2. 如果希望從IntentService改回BroadcastReceiver可參考該方法
*/
fun setBroadcastReceiver() {
getCloudPushService().setPushIntentService(null)
}
interface Callback {
fun isSuccess(isSuccess: Boolean)
}
}
參考
阿里雲移動推送開發文檔 https://help.aliyun.com/product/30047.html?spm=a2c4g.750001.list.119.6b9e7b13hCCqDp