1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Android 推送集成华为 小米 友盟

Android 推送集成华为 小米 友盟

时间:2020-05-23 12:24:38

相关推荐

Android 推送集成华为 小米 友盟

公司的 app 一直使用的是极光推送,最近反馈比较多的是推送消息收不到,看来需要找新的推送服务了,在国内目前手机品牌占有率比较多的是华为和小米,且这两家都有自己的推送服务,同时一个合作的友商说他们使用的是友盟推送,推送率还不错,那么就测试这三个推送服务了。

按照集成的难易程度排序

友盟推送

官网链接Push 接入说明书

接入步骤

官网有提供了视频和文档,很详细,而且很简单。

小米推送

官网链接Push 接入说明书

接入步骤

在小米推送运营平台创建应用,地址点这里, 获取到 AppID , AppKey把从小米下载的 jar 放到 libs 下

在 AndroidManifest.xml 中添加权限

<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.READ_PHONE_STATE" /><uses-permission android:name="android.permission.GET_TASKS" /><uses-permission android:name="android.permission.VIBRATE"/><permission android:name="com.xxx.xxx.permission.MIPUSH_RECEIVE" android:protectionLevel="signature" /><uses-permission android:name="com.xxx.xxx.permission.MIPUSH_RECEIVE" />

配置推送服务需要的service和receiver

<serviceandroid:enabled="true"android:process=":pushservice"android:name="com.xiaomi.push.service.XMPushService"/><serviceandroid:name="com.xiaomi.push.service.XMJobService"android:enabled="true"android:exported="false"android:permission="android.permission.BIND_JOB_SERVICE"android:process=":pushservice" /><!--注:此service必须在3.0.1版本以后(包括3.0.1版本)加入--><serviceandroid:enabled="true"android:exported="true"android:name="com.xiaomi.mipush.sdk.PushMessageHandler" /> <service android:enabled="true"android:name="com.xiaomi.mipush.sdk.MessageHandleService" /> <!--注:此service必须在2.2.5版本以后(包括2.2.5版本)加入--><receiverandroid:exported="true"android:name="com.xiaomi.push.workStatusReceiver" ><intent-filter><action android:name=".conn.CONNECTIVITY_CHANGE" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></receiver><receiverandroid:exported="false"android:process=":pushservice"android:name="com.xiaomi.push.service.receivers.PingReceiver" ><intent-filter><action android:name="com.xiaomi.push.PING_TIMER" /></intent-filter></receiver>

自定义一个BroadcastReceiver类

public class MiMessageReceiver extends PushMessageReceiver {private static final String TAG = "MiMessageReceiver";private String mRegId;private String mTopic;private String mAlias;private String mAccount;private String mStartTime;private String mEndTime;@Overridepublic void onNotificationMessageClicked(Context context, MiPushMessage message) {Log.v(MyApplication.TAG,"onNotificationMessageClicked is called. " + message.toString());if (!TextUtils.isEmpty(message.getTopic())) {mTopic = message.getTopic();Log.e(TAG, mTopic);} else if (!TextUtils.isEmpty(message.getAlias())) {mAlias = message.getAlias();Log.e(TAG, mAlias);}}@Overridepublic void onNotificationMessageArrived(Context context, MiPushMessage message) {Log.v(MyApplication.TAG,"onNotificationMessageArrived is called. " + message.toString());String log = "Arrived a notification message. Content is " + message.getContent();if (!TextUtils.isEmpty(message.getTopic())) {mTopic = message.getTopic();} else if (!TextUtils.isEmpty(message.getAlias())) {mAlias = message.getAlias();}}@Overridepublic void onCommandResult(Context context, MiPushCommandMessage message) {Log.v(TAG,"onCommandResult is called. " + message.toString());String command = message.getCommand();List<String> arguments = message.getCommandArguments();String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);String cmdArg2 = ((arguments != null && arguments.size() > 1) ? arguments.get(1) : null);String log;if (MAND_REGISTER.equals(command)) {if (message.getResultCode() == ErrorCode.SUCCESS) {mRegId = cmdArg1;Log.e(TAG, "Register push success.");} else {Log.e(TAG, "Register push fail.");}} else {log = message.getReason();}}@Overridepublic void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {Log.v(TAG,"onReceiveRegisterResult is called. " + message.toString());String command = message.getCommand();List<String> arguments = message.getCommandArguments();String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);if (MAND_REGISTER.equals(command)) {if (message.getResultCode() == ErrorCode.SUCCESS) {mRegId = cmdArg1;Log.e(TAG, "Register push success.");} else {Log.e(TAG, "Register push fail.");}}}}

在 AndroidManifest.xml 中注册该广播

<receiverandroid:name=".MiMessageReceiver"android:exported="true"><intent-filter><action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/></intent-filter><intent-filter><action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/></intent-filter><intent-filter><action android:name="com.xiaomi.mipush.ERROR"/></intent-filter></receiver>

在 Application 中初始化推送服务

private void initMiPush() {//初始化push推送服务if (shouldInit()) {MiPushClient.registerPush(this, MI_APP_ID, MI_APP_KEY);}//打开LogLoggerInterface newLogger = new LoggerInterface() {@Overridepublic void setTag(String tag) {// ignore}@Overridepublic void log(String content, Throwable t) {Log.d(TAG, content, t);}@Overridepublic void log(String content) {Log.d(TAG, content);}};Logger.setLogger(this, newLogger);}private boolean shouldInit() {ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();String mainProcessName = getPackageName();int myPid = android.os.Process.myPid();for (ActivityManager.RunningAppProcessInfo info : processInfos) {if (info.pid == myPid && mainProcessName.equals(info.processName)) {return true;}}return false;}

华为推送

官网链接Push 接入说明书

接入步骤(HMS-SDK版本:2.4.0.300):

把从华为 Push 推送官网下载的 aar ,位于:...\HMS-2.4.0.300\HWHMS-SDK-v2.4.0.300\libs\HMS-SDK-2.4.0.300.aar,放到工程目录的 aars 下(没有该目录的新建一个)

在 AndroidManifest.xml 文件的 Application 节点添加: meta-data 和自定义的 Receiver,如下(其中 meta-data 中的 appId 是在网页上创建应用的 id,我的是一个 8 位的数字):

<meta-dataandroid:name="com.huawei.hms.client.appid"android:value="appId"></meta-data><!-- 第三方相关 :接收Push消息(注册、Push消息、Push连接状态)广播 --><receiver android:name=".HuaweiPushReceiver"><intent-filter><!-- 必须,用于接收token --><action android:name="com.huawei.android.push.intent.REGISTRATION"/><!-- 必须,用于接收消息 --><action android:name="com.huawei.android.push.intent.RECEIVE"/><!-- 可选,用于点击通知栏或通知栏上的按钮后触发onEvent回调 --><action android:name="com.huawei.android.push.intent.CLICK"/><!-- 可选,查看push通道是否连接,不查看则不需要 --><action android:name="com.huawei.intent.action.PUSH_STATE"/></intent-filter><meta-dataandroid:name="CS_cloud_ablitity"android:value="@string/hwpush_ability_value"/></receiver>

在 AndroidManifest.xml 文件中添加权限

<uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.WAKE_LOCK" /><uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

在 MainActivity 或者 BaseAcitivty 中初始化华为 Push ,放在 onCreate() 中初始化华为 Push

private void initHuaweiPush(Context context) {HuaweiIdSignInOptions options = new HuaweiIdSignInOptions.Builder(HuaweiIdSignInOptions.DEFAULT_SIGN_IN).build();mClient = new HuaweiApiClient.Builder(context).addApi(HuaweiPush.PUSH_API).addConnectionCallbacks(new HuaweiApiClient.ConnectionCallbacks() {@Overridepublic void onConnected() {getToken();runOnUiThread(new Runnable() {@Overridepublic void run() {tv.setText("HUAWEI onConnected, IsConnected: " + mClient.isConnected());}});Log.e(TAG, "HUAWEI onConnected, IsConnected: " + mClient.isConnected());}@Overridepublic void onConnectionSuspended(final int i) {runOnUiThread(new Runnable() {@Overridepublic void run() {tv.setText("HUAWEI onConnectionSuspended, cause: " + i + ", IsConnected:" +" " +mClient.isConnected());}});Log.e(TAG, "HUAWEI onConnectionSuspended, cause: " + i + ", IsConnected:" +" " +mClient.isConnected());}}).addOnConnectionFailedListener(new HuaweiApiClient.OnConnectionFailedListener() {@Overridepublic void onConnectionFailed(@NonNull final ConnectionResultconnectionResult) {runOnUiThread(new Runnable() {@Overridepublic void run() {tv.setText("HUAWEI onConnectionFailed, ErrorCode: " + connectionResult.getErrorCode());}});Log.e(TAG, "HUAWEI onConnectionFailed, ErrorCode: " + connectionResult.getErrorCode());}}).build();mClient.connect();}@Overrideprotected void onStart() {super.onStart();mClient.connect();}private void getToken() {if (!isConnected()) {tv.setText("get token failed, HMS is disconnect.");return;}// 同步调用方式,不会返回token,通过广播的形式返回。new Thread(new Runnable() {@Overridepublic void run() {PendingResult<TokenResult> token = HuaweiPush.HuaweiPushApi.getToken(mClient);token.await();}}).start();}public boolean isConnected() {if (mClient != null && mClient.isConnected()) {return true;} else {return false;}}

新建 HuaweiPushReceiver ,继承 PushReceiver,重写 onToken() ,onPushMsg(),onEvent(),onPushState(),在 onToken() 中可以获取到 token。

public class HuaweiPushReceiver extends PushReceiver {private static final String TAG = "Huawei PushReceiver";@Overridepublic void onToken(Context context, String token, Bundle extras) {String belongId = extras.getString("belongId");String content = "get token and belongId successful, token = " + token + ",belongId = " + belongId;Log.d(TAG, content);}@Overridepublic boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {try {String content = "-------Receive a Push pass-by message: " + new String(msg, "UTF-8");Log.d(TAG, content);} catch (Exception e) {e.printStackTrace();}return false;}public void onEvent(Context context, PushReceiver.Event event, Bundle extras) {if (Event.NOTIFICATION_OPENED.equals(event) || Event.NOTIFICATION_CLICK_BTN.equals(event)) {int notifyId = extras.getInt(BOUND_KEY.pushNotifyId, 0);if (0 != notifyId) {NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);manager.cancel(notifyId);}String content = "--------receive extented notification message: " + extras.getString(BOUND_KEY.pushMsgKey);Log.d(TAG, content);}super.onEvent(context, event, extras);}@Overridepublic void onPushState(Context context, boolean pushState) {try {String content = "---------The current push status: " + (pushState ? "Connected" :"Disconnected");Log.d(TAG, content);} catch (Exception e) {e.printStackTrace();}}}

获取到 token 以后就连接成功了。可以测试推送了。

非华为手机使用华为推送需要安装-华为移动服务.apk

各个版本EMUI对push的支持情况

华为手机上:

Emui3.0上,Push广播有很大概率被限制,如: Mate7 3.0版本,荣耀6plus,P7 3.0版本,4X, 4A等。

Emui3.1上,Push广播基本不被限制,但个别型号机型存在问题,如:荣耀5x等。

Emui4.0及以上,Push广播有较高概率被限制,不被限制的机型如:荣耀畅玩4C,荣耀畅玩4X,Mate S,P8 MAX等。

Emui4.1 , ROM升级到了最新版本的(80%已升),通知消息不走广播,不会被限制,透传消息走广播,会被限制。

Emui5.0以上 ,通知消息不走广播,不会被限制,透传消息走广播,会被限制。

如广播被限制,需要将应用设为开机启动项。所以对于及时性或到达率要求非常高的应用,我们建议应用要考虑替代方案。

非华为手机:

第三方手机(如:小米、OPPO、三星等),由于rom的限制,需要将应用 设为开机启动项。

测试设备

Samsung S4(Android 5.0)HTC D820u(Android 6.0)Huawei P8(Android 6.0)Xiaomi Note(Android 7.0)Samsung S7(Android 7.0)LG Nexus 6(Android 7.0)Huawei Mate8(Android 7.0)Huawei Mate9(Android 7.0)

测试数据

三家推送比较

华为推送在非华为手机上必须安装华为移动服务,这点比较的坑,用户可能不会同意安装的,那就没得玩了,只适合在华为手机上使用。华为推送还得区别 Emui 的版本,这玩意也不是个小坑,虽然官方QQ群公告说 Emui 5.0 以后都可以收到消息推送,但是不知道靠谱不靠谱友盟推送的话,在测试阶段,发现三星S7(Android 7.0),三星S4(Android 5.0),华为P8(Android 6.0)无法获取到 token,没有 token ,那就推送不了了。小米推送还可以,但是在三星 S4(Android 5.0) 上无法接收到推送。综上,app 需要集成华为推送和小米推送比较的靠谱点,针对华为手机使用华为推送,其他手机使用小米推送。使用中的大坑,在华为手机上假如华为移动服务不是最新版本或者被卸载了,推送服务无法使用。必须在 app 中提示用户更新或安装,真是一个大坑,关键是更新界面丑的要死,还会出现更新失败的情况,坑人呀。针对小米推送,在非小米设备上会出现重启以后无法获得推送,因为是重启以后,小米的 XMPushService 没有起来,目前采用的办法是监听手机启动广播,然后启动小米的 XMPushService。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。