阿里雲移動推送學習筆記

阿里雲移動推送學習筆記

第一步:項目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

阿里雲官網地址:https://homenew.console.aliyun.com/

第四步: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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章