Android推送实践总结

996 阅读3分钟

前提条件

这篇文章主要讲集成阿里的EMAS推送过程中的一些坑和接入流程,主要是对接入过程的一个总结(毕竟浪费了我3天时间)。

  • 开通了EMAS服务并创建了应用(创建方式
  • 创建了各厂商的应用(国内的厂商必须有,要不然离线状态收不到通知,三星除外(貌似也不算国内厂商-O-))

接入SDK

接入方式官方文档上已写好步骤,这里就不重复赘述了,这里只做个总结。

  1. 工程的setting.gradle中添加阿里云仓库,代码如下:

pluginManagement {
    repositories {
        ...
        maven { url "https://maven.aliyun.com/nexus/content/repositories/releases/" }
    }
}
dependencyResolutionManagement {
//    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        ...
        maven { url "https://maven.aliyun.com/nexus/content/repositories/releases/" }
        maven {url 'https://developer.huawei.com/repo/'}//接入华为推送时需要
    }
}

  1. 工程的build.gradle中添加gradle依赖
buildscript {
    dependencies {
        ...
        classpath 'com.aliyun.ams:emas-services:1.0.4'//可以在阿里云仓库查找最新的版本:https://developer.aliyun.com/mvn/search
    }
}
  1. 在项目app的build.gradle下面添加插件和依赖,并在同级目录下添加配置文件aliyun-emas-services.json

    所有依赖版本均可在阿里云仓库找到最新版本:developer.aliyun.com/mvn/search

plugins {
    ...
    id 'com.aliyun.ams.emas-services'
}
android {
    defaultConfig {
        ...
        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86_64'//你支持的cpu架构
        }
}
dependencies {
    implementation 'com.alipay.sdk:alipaysdk-android:15.8.12'//阿里云基础依赖
    implementation 'com.aliyun.ams:alicloud-android-push:3.8.4.1'//推送依赖
    implementation 'com.aliyun.ams:alicloud-android-third-push:3.8.4'//辅助推送依赖使用厂商推送时需要,提高到达率
    implementation 'com.aliyun.ams:alicloud-android-third-push-xiaomi:3.8.4'
    implementation 'com.aliyun.ams:alicloud-android-third-push-huawei:3.8.4'
    implementation 'com.aliyun.ams:alicloud-android-third-push-vivo:3.8.4'
    implementation 'com.aliyun.ams:alicloud-android-third-push-oppo:3.8.4'
}
  1. aliyun-emas-services.json中配置信息修改

    aliyun-emas-services.json中包含多种服务,对应有status来控制是否启用,1为启用0为不启用,推送服务对应为cps_service,如果只用推送可以只开启这个服务具体可看文档

{
  "config": {
   "emas.appKey":"*******",
   "emas.appSecret":"*******",
   "emas.packageName":"*******",
   "hotfix.idSecret":"*******",
   "hotfix.rsaSecret":"*******",
   "httpdns.accountId":"*******",
   "httpdns.secretKey":"*******",
   "appmonitor.tlog.rsaSecret":"*******",
   "appmonitor.rsaSecret":"*******"
},
  "services": {
   "hotfix_service":{//移动热修复
      "status":0,
      "version":"3.3.8"
   },
   "ha-adapter_service":{//性能分析/远程日志基础库
      "status":0,
      "version":"1.1.5.4-open"
   },
   "feedback_service":{//移动用户反馈
      "status":0,
      "version":"3.4.2"
   },
   "tlog_service":{//远程日志
      "status":0,
      "version":"1.1.4.5-open"
   },
   "httpdns_service":{//HTTPDNS
      "status":0,
      "version":"2.3.0-intl"
   },
   "apm_service":{//性能分析
      "status":0,
      "version":"1.1.1.0-open"
   },
   "man_service":{
      "status":1,
      "version":"1.2.7"
   },
   "cps_service":{//移动推送
      "status":1,
      "version":"3.8.4.1"
   }
},
  "use_maven":true,//true表示使用远程依赖,false表示使用本地libs依赖
  "proguard_keeplist":"********"
}
  1. 项目app的AndroidManifest.xml文件中配置appkey
...
<uses-permission android:name="android.permission.INTERNET" /> <!-- 网络访问 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 检查Wi-Fi网络状态 -->
<uses-permission android:name="android.permission.GET_TASKS" /> <!-- 推送使用,运行状态 -->
<uses-permission android:name="android.permission.REORDER_TASKS" /> <!-- 推送使用,运行状态 -->
<application
    android:allowBackup="false" 
    tools:replace="android:allowBackup">
    <meta-data
        android:name="com.alibaba.app.appkey"
        android:value="阿里云的APPKEY" />
    <meta-data
        android:name="com.alibaba.app.appsecret"
        android:value="阿里云的appsecret" />
    <meta-data
        android:name="com.huawei.hms.client.appid"
        android:value="appid=华为的appid" />
    <meta-data
        android:name="com.vivo.push.api_key"
        android:value="vivo的apikey" />
    <meta-data
        android:name="com.vivo.push.app_id"
        android:value="vivo的appid" />

    <receiver
        android:name=".push.PushReceiver"//接收通知的广播继成自MessageReceiver当app为在线状态或走阿里云通道时调用
        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>

    <activity
        android:name=".push.PushPopupActivity"//辅助推送Activity继成自AndroidPopupActivity当走厂商渠道通知被点击时调用到onSysNoticeOpened()方法中
        android:exported="true"
        android:label="@string/title_activity_third_push_notice"
        android:launchMode="singleInstance"
        android:screenOrientation="portrait" >
        <!-- scheme 配置开始 vivo通道需要添加 -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data
                android:host="${applicationId}"
                android:path="/thirdpush"
                android:scheme="agoo" />
        </intent-filter>
        <!-- scheme 配置结束  -->
    </activity>

  1. 初始化SDK

    在Application的onCreate()方法中初始化

open class BaseApp : Application() {
    override fun onCreate() {
        super.onCreate()
        PushServiceFactory.init(this)
        initNotificationChannel(this)
        MiPushRegister.register(this, "小米的appid", "小米的appkey")
        HuaWeiRegister.register(this)
        VivoRegister.register(this)
        OppoRegister.register(this,"oppo的appkey","oppo的appSecret")
        val pushService = PushServiceFactory.getCloudPushService()
        if (ProjectSwitch.isDebug) {
            pushService.setLogLevel(CloudPushService.LOG_DEBUG) //仅适用于Debug包,正式包不需要此行
        }
        pushService.setNotificationShowInGroup(true)
        pushService.register(this, object : CommonCallback {
            override fun onSuccess(response: String?) {
            }
            override fun onFailed(errorCode: String, errorMessage: String) {
            }
        })
    }

    private fun initNotificationChannel(context: Context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mNotificationManager: NotificationManager? =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
            // 通知渠道的id,后台推送选择渠道时对应的id。
            val id = "1"
            // 用户可以看到的通知渠道的名字。
            val name: CharSequence = "通知渠道的名字"
            // 用户可以看到的通知渠道的描述。
            val description = "渠道的描述"
            val importance: Int = NotificationManager.IMPORTANCE_HIGH
            val mChannel = NotificationChannel(id, name, importance)
            // 配置通知渠道的属性。
            mChannel.setDescription(description)
            // 设置通知出现时的闪灯(如果Android设备支持的话)。
            mChannel.enableLights(true)
            mChannel.setLightColor(Color.RED)
            // 设置通知出现时的震动(如果Android设备支持的话)。
            mChannel.enableVibration(true)
            mChannel.setVibrationPattern(longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400))
            // 最后在notificationmanager中创建该通知渠道。
            mNotificationManager?.createNotificationChannel(mChannel)
        }
    }
}

各厂商集成步骤

查看官方辅助通道集成文档help.aliyun.com/document_de…

问题处理

完成上面一堆后本以为可以大功告成了吗,no~no~no~,怎么可能这么简单,接下来就是踩坑之旅了。

  1. Android13对通知做了权限控制,需要显示请求通知权限:developer.android.google.cn/about/versi…
  2. 各厂商对通知做了限制处理,导致必须申请对应渠道才能正常使用通知: