最近因为公司后台服务器买的是阿里云的服务,所以把友盟的推送换成了阿里云推送,首先不得不说,文档写得很差,兼容性和适配做得也不是很好,加了技术支持群,但是里面的同学问一个问题半天才有回复,好了,不扯谈,直接上代码。
1.添加依赖:
由于公司项目是组件化开发,所以我把推送也单独做成了一个组件,可以独立运行.在项目的统一依赖管理config.gradle添加阿里云推送的依赖和各第三方渠道的依赖,如下图所示: 如有疑问和版本更新,可以去阿里云官网查看,这里就不说这些了
![在这里插入图片描述](https://img-blog.csdnimg.cn/84834625b98d42198f68649debefc0f3.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5reh5reh55qE6aaZ54Of,size_20,color_FFFFFF,t_70,g_se,x_16)
// 主通道依赖
"ali_push" : 'com.aliyun.ams:alicloud-android-push:3.4.0',
// 辅助通道基础依赖
"third_push" : 'com.aliyun.ams:alicloud-android-third-push:3.4.0',
// 华为依赖
"push-huawei" : 'com.aliyun.ams:alicloud-android-third-push-huawei:3.4.0',
// 小米依赖
"push-xiaomi" : 'com.aliyun.ams:alicloud-android-third-push-xiaomi:3.4.0',
// OPPO依赖
"push-oppo" : 'com.aliyun.ams:alicloud-android-third-push-oppo:3.4.0',
// vivo依赖
"push-vivo" : 'com.aliyun.ams:alicloud-android-third-push-vivo:3.4.0',
// 魅族依赖
"push-meizu" : 'com.aliyun.ams:alicloud-android-third-push-meizu:3.4.0',
// 谷歌依赖
"push-fcm" : 'com.aliyun.ams:alicloud-android-third-push-fcm:3.4.0',
// 公共依赖库
"alicloud-utdid" : 'com.aliyun.ams:alicloud-android-utdid:2.5.1-proguard',
"alicloud-utils" : 'com.aliyun.ams:alicloud-android-utils:1.1.6.4',
"alicloud-ut" : 'com.aliyun.ams:alicloud-android-ut:5.4.4',
"alicloud-beacon" : 'com.aliyun.ams:alicloud-android-beacon:1.0.5',
2.Manifast配置如下:这里的appid和key填上你自己项目的即可.
3.初始化:推送组件我做成了接口的形式,外部不用相互依赖即可直接调用,调用很方便,代码耦合行也不高,现在的组件化开发就得这样,不用每个模块相互依赖或引用,代码如下:
推送基础的接口管理类:IPushActions
接口管理类封装了以下方法:
初始化、推送开关是否开启、设置别名、设置tag、绑定账号、移除别名、解绑tag、开启推送、关闭推送、解绑账号、查询所有别名、查询所有tag这些主要的方法
public interface IPushActions {
//初始化
void setDebugMode(boolean isDebugMode);
//初始化
void initPush(Application application);
//推送是否关闭
boolean isPushStopped(Context context);
//setAlias 阿里
void setAlias(Context context,String psnCode);
//解绑标签
void unBindTag(Context context, int target, String[] tags);
//setTags 阿里
void setTags(Context context, String[] tags);
//移除别名
void removeAlias(Context context, String alias);
void openPush();
void closePush();
boolean isStopPush(Context context);
void stopJPush(Context context);
void resumeJPush(Context context);
//绑定账号
void bindAccount(Context context,String userId);
//解绑账号
void unbindAccount(Context context,String userId);
//查询所有tag
void listTags(Context context,int target);
//查询所有别名
void listAliases(Context context);
}
4.初始化的代码在Mainapplication中也就一句话,如下图:
5.同学们有没有觉得很方便,因为我基于推送接口类写了一个推送的管理类,在上面设置tag和别名的基础方法之上写了具体初始化和各种绑定解绑逻辑,截图如下:
6.这里的代码只是参考,同志们根据自己的逻辑进行调整,完整代码如下:
package com.powervision.lib_ali_push.manager;
import android.app.Application;
import android.content.Context;
import com.alibaba.sdk.android.push.CloudPushService;
import com.alibaba.sdk.android.push.CommonCallback;
import com.alibaba.sdk.android.push.huawei.HuaWeiRegister;
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
import com.alibaba.sdk.android.push.register.GcmRegister;
import com.alibaba.sdk.android.push.register.MeizuRegister;
import com.alibaba.sdk.android.push.register.MiPushRegister;
import com.alibaba.sdk.android.push.register.OppoRegister;
import com.alibaba.sdk.android.push.register.VivoRegister;
import com.blankj.utilcode.util.AppUtils;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.powervision.lib_ali_push.component.MyMessageIntentService;
import com.powervision.lib_common.contants.AppUseConstant;
import com.powervision.lib_common.utils.LogUtils;
import com.powervision.lib_push.IPushActions;
import com.powervision.pvcamera.lib_alipush.BuildConfig;
import java.util.Arrays;
import java.util.List;
/**
@auth: njb
@date: 2021/8/6 9:57
@desc: 描述
*/
public class AliPushManager implements IPushActions {
private static AliPushManager mPushManager;
private String TAG = “AliPushManager”;
CloudPushService pushService;
private FirebaseApp firebaseApp;
private AliPushManager() {
}
public static AliPushManager getInstance() {
if (mPushManager == null) {
mPushManager = new AliPushManager();
}
return mPushManager;
}
@Override
public void setDebugMode(boolean isDebugMode) {
if (pushService != null) {
//调试是否打开
pushService.setDebug(isDebugMode);
//设置日志级别
pushService.setLogLevel(CloudPushService.LOG_DEBUG);
}
}
@Override
public void initPush(final Application application) {
pushService = PushServiceFactory.getCloudPushService();
pushService.setPushIntentService(MyMessageIntentService.class);
pushService.register(application, new CommonCallback() {
@Override
public void onSuccess(String response) {
LogUtils.d(TAG, “init cloudchannel success”);
AliPushManager.getInstance().setAlias(application, PushTagUtils.getDeviceId());
AliPushManager.getInstance().setTags(application, PushTagUtils.getTag());
}
@Override
public void onFailed(String errorCode, String errorMessage) {
LogUtils.d(TAG, "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage);
}
});
//初始化辅助渠道推送
initThirdPush(application);
AliPushManager.getInstance().setDebugMode(BuildConfig.DEBUG);
setPushService(pushService);
}
private void initThirdPush(Application application) {
// 初始化小米辅助推送
MiPushRegister.register(application, AppUseConstant.XIAOMI_APP_ID, AppUseConstant.XIAOMI_APP_KEY);
// 接入华为辅助推送
HuaWeiRegister.register(application);
// 接入ViVo初始化推送
VivoRegister.register(application);
// 接入Opp)初始化推送
OppoRegister.register(application, AppUseConstant.OPPO_APP_KEY, AppUseConstant.OPPO_APP_Secret);
// 接入MeiZu初始化推送
MeizuRegister.register(application, “MEIZU_ID”, “MEIZU_KEY”);
// 接入FCM/GCM初始化推送
GcmRegister.register(application, AppUseConstant.GCM_SEND_ID, AppUseConstant.GOOGLE_APP_ID);
//注册FireBase
initFireBaseApp(application);
}
private void initFireBaseApp(Application application) {
FirebaseOptions options = new FirebaseOptions.Builder()
.setApplicationId(AppUseConstant.GOOGLE_APP_ID)
.setGcmSenderId(AppUseConstant.GCM_SEND_ID)
.setApiKey(AppUseConstant.GOOGLE_API_KEY).build();
boolean hasBeenInitialized = false;
List firebaseApps = FirebaseApp.getApps(application);
for (FirebaseApp app : firebaseApps) {
if (app.getName().equals(FirebaseApp.DEFAULT_APP_NAME)) {
hasBeenInitialized = true;
firebaseApp = app;
}
}
//判断是否注册
if (!hasBeenInitialized) {
firebaseApp = FirebaseApp.initializeApp(application, options, AppUtils.getAppName());
}
}
public void setPushService(CloudPushService pushService) {
this.pushService = pushService;
}
public CloudPushService getPushService() {
return pushService;
}
@Override
public boolean isPushStopped(Context context) {
return false;
}
@Override
public void setAlias(final Context context, final String alias) {
if (pushService != null) {
pushService.addAlias(alias, new CommonCallback() {
@Override
public void onSuccess(String s) {
LogUtils.d(TAG, alias + " success 别名绑定成功");
}
@Override
public void onFailed(String errorCode, String errorMsg) {
LogUtils.d(TAG, alias + " failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
}
}
@Override
public void unBindTag(final Context context, final int target, final String[] tags) {
if (pushService != null) {
pushService.unbindTag(target, tags, null, new CommonCallback() {
@Override
public void onSuccess(String response) {
LogUtils.d(TAG, “success tag解绑成功” + tags);
AliPushManager.getInstance().setTags(context, PushTagUtils.getTag());
}
@Override
public void onFailed(String errorCode, String errorMsg) {
LogUtils.d(TAG, " failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
}
}
@Override
public void setTags(Context context, final String[] tags) {
if (pushService != null) {
pushService.bindTag(CloudPushService.DEVICE_TARGET, tags, “”, new CommonCallback() {
@Override
public void onSuccess(String s) {
LogUtils.d(TAG, " success 标签绑定成功" + Arrays.toString(tags));
}
@Override
public void onFailed(String errorCode, String errorMsg) {
LogUtils.d(TAG, tags + " failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
}
}
@Override
public void removeAlias(final Context context, final String alias) {
if (pushService != null) {
pushService.removeAlias(alias, new CommonCallback() {
@Override
public void onSuccess(String response) {
LogUtils.d(TAG, alias + " success 别名解绑成功");
LogUtils.d(TAG, AppUseConstant.ALIAS + " --解绑前的别名—");
if (!AppUseConstant.isUnBind) {
AppUseConstant.ALIAS = PushTagUtils.getDeviceId();
LogUtils.d(TAG, AppUseConstant.ALIAS + " --解绑后的别名—");
AliPushManager.getInstance().setAlias(context, AppUseConstant.ALIAS);
}
}
@Override
public void onFailed(String errorCode, String errorMsg) {
LogUtils.d(TAG, " failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg);
}
});
}
}
@Override
public void openPush() {
if (pushService != null) {
pushService.turnOnPushChannel(new CommonCallback() {
@Override
public void onSuccess(String s) {
com.blankj.utilcode.util.LogUtils.d(“turn on push channel success”);
}
@Override
public void onFailed(String errorCode, String errorMsg) {
com.blankj.utilcode.util.LogUtils.d("turn on push channel failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
}
}
@Override
public void closePush() {
if (pushService != null) {
pushService.turnOffPushChannel(new CommonCallback() {
@Override
public void onSuccess(String s) {
com.blankj.utilcode.util.LogUtils.d(“turn off push channel success”);
}
@Override
public void onFailed(String errorCode, String errorMsg) {
com.blankj.utilcode.util.LogUtils.d("turn off push channel failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
}
}
@Override
public boolean isStopPush(Context context) {
return false;
}
@Override
public void stopJPush(Context context) {
}
@Override
public void resumeJPush(Context context) {
}
@Override
public void bindAccount(Context context, String userId) {
final String account = userId;
if (pushService != null) {
pushService.bindAccount(account, new CommonCallback() {
@Override
public void onSuccess(String s) {
LogUtils.d(TAG, account + " 账号绑定成功 success\n");
}
@Override
public void onFailed(String errorCode, String errorMsg) {
LogUtils.d(TAG, account + " failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg);
}
});
}
}
@Override
public void unbindAccount(Context context, final String account) {
if (pushService != null) {
pushService.bindAccount(account, new CommonCallback() {
@Override
public void onSuccess(String s) {
LogUtils.d(TAG, s + “unbind account success 解绑账号成功”);
}
@Override
public void onFailed(String errorCode, String errorMsg) {
LogUtils.d(TAG, "bind account failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
}
}
@Override
public void listTags(final Context context, final int target) {
if (pushService != null) {
pushService.listTags(target, new CommonCallback() {
@Override
public void onSuccess(String response) {
LogUtils.d(TAG, response + " success 查询标签成功");
if (response.contains(Arrays.toString(PushTagUtils.getTag()))) {
AliPushManager.getInstance().unBindTag(context, CloudPushService.DEVICE_TARGET, PushTagUtils.getTag());
} else {
bindTag(context, PushTagUtils.getTag());
}
}
@Override
public void onFailed(String errorCode, String errorMsg) {
LogUtils.d(TAG, " failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg);
}
});
}
}
private void bindAlias(Context context, String alias) {
LogUtils.d(TAG, alias);
if (alias.isEmpty()) {
return;
}
AliPushManager.getInstance().setAlias(context, alias);
}
private void bindTag(Context context, String[] tags) {
AliPushManager.getInstance().setTags(context, tags);
//LogUtils.d(TAG, String.valueOf(tags));
}
@Override
public void listAliases(final Context context) {
if (pushService != null) {
pushService.listAliases(new CommonCallback() {
@Override
public void onSuccess(String response) {
LogUtils.d(TAG, response + " success 别名查询成功");
}
@Override
public void onFailed(String errorCode, String errorMsg) {
LogUtils.d(TAG, " failed." + "errorCode: " + errorCode + ", errorMsg:" + errorMsg);
}
});
}
}
}
7.遇到的问题:
a.初始化的时候一定要在隐私协议同意之后进行,相信集成友盟和sharesdk等第三方的同学一定会遇到这个问题,这里分两步,1是与初始化,这个方法不会获取设备信息,不用请求权限,2是需要在用户同意隐私协议之后初始化的方法,当然阿里云官网也给出了说明,说明如下:
b.阿里云推送和第三方辅助渠道在初始化时一定要在主线程中进行,不然会出现App在后台或者被杀死收到通知,但是进程没有拉起来的情况,代码如下:
判断是否为主进程的方法如下:
/**
* 当前进程是否为主进程
*
* @return True-是 False-否
*/
private boolean isMainProcess() {
// 获取当前包名
String packageName = this.getPackageName();
// 获取当前进程名
String processName = getProcessName(android.os.Process.myPid());
return processName == null || processName.equals(packageName);
}
c.在初始化第三方辅助渠道的时候,一定要仔细看文档,检查各个应用市场的key,因为这些配置关系到App退到后台和被杀死的情况下推送问题。这里特别说明一下!!!Oppo辅助渠道初始化的时候第三个参数不是appkey,也不是appid,而是appsecret,这里本同学刚开始也是填写错误,导致oppo手机一直注册失败,找了半天文档和资料才发现问题,所以接第三方一定要仔细,把文档和步骤看懂在开始写代码,要不然上来咔咔一顿操作猛于虎,但是发现出问题就蒙蔽了,完全找不到原因.
d.google的fcm推送国内由于用不了的原因,测试的时候一定要开启,要不然会导致开启google服务失败而收不到离线通知。fcm初始化也要注意重复初始化的问题,如下图:
e.各大第三方辅助通道初始化成功的截图如下:
google gcm:
huawei:
xiaomi:
Oppo:
Vivo:
如果没有获取到上面的token,请仔细检查各种配置:
1.阿里云的推送后台:这里需要注意的是Oppo填写的第2个可以是MasterSecret,而不是appsecret,很多同学不注意也会填错,这个去oppo开放平台获取你本应用的就好.
2.华为的配置:
https://help.aliyun.com/document_detail/190012.html
!!! 这里需要注意的是华为需要开通消息回执和配置SHA256证书指纹,要不然会一直提示初始化失败,本同学刚开始没有配置指纹证书,导致注册时一直获取不到华为推送渠道注册成功的token.
今天由于时间原因先到这里,后面会给出小米、oppo、vivo、gcm的具体配置和问题,目前各大平台的离线推送都很及时,当然,这里和我们公司付费有一定关系,还有提示用户打开各种通知权限,后面也会讲解.