友盟推送算是比较好用的一种免费推送,集成简单,但是在使用中有一个问题,友盟的deviceToken获取,是根据手机来进行的, 也就是说,一个手机,一个deviceToken,除非app卸载重新安装或一些其他原因造成deviceToken过期,否则deviceToken是不会更换的
这时候就有了一个问题,如果,你的手机登陆了账号A,获得了deviceToken并后台进行推送,一切正常,这时候,你退出了A,在登录了账号B,这时候后台根据deviceToken推送,B也是能收到的,因为两者deviceToken一致。
如果说反正都是推送,都要接受,无所谓了,那么换一种情况,还是登录A,而A拥有的控制权限,会推送所有关于项目的报警信息等,而这时,你把手机借给客户体验app,让他注册了个新账号B登录,理所当然,B是客户,不可能拥有所有控制权限的,也就是说,关于项目的报警信息,他应该一条也收不到,而这时问题就体现出来了,A一开始先登录的,deviceToken已经发送上去了,你这时登录B,用的也是同一个deviceToken,也就意味着, 发送给A的信息,B也能收到。
后果不用再说了吧?反正总监之类的找来是肯定的,那就需要进行处理了。
首先,友盟出了根据deviceToken进行推送,也支持别名推送,根据别名,来对deviceToken进行绑定,这样来避免推送错误的问题。
//别名绑定,将某一类型的别名ID绑定至某设备,老的绑定设备信息被覆盖,别名ID和deviceToken是一对一的映射关系 PushAgent mPushAgent = PushAgent.getInstance(this); mPushAgent.addAlias("你与后台商定的用来区分用户的不能相同的", "可以是写死的别名项目名随意", new UTrack.ICallBack() { @Override public void onMessage(boolean isSuccess, String message) { Log.e("TAG","别名:绑定isSuccess"+isSuccess+" message:"+message); } });
而除了绑定,还要移除别名,在退出登录的时候进行处理
//移除别名ID PushAgent mPushAgent = PushAgent.getInstance(MainSettingActivity.this); //移除别名ID String loginName = CacheUtil.getString(getApplicationContext(), "loginName", ""); mPushAgent.removeAlias("你与后台商定的用来区分用户的不能相同的", "可以是写死的别名项目名随意", new UTrack.ICallBack() { @Override public void onMessage(boolean b, String s) { Log.e("TAG","别名:退出登录解除绑定isSuccess"+b+" message:"+s); } });
关于这个方法介绍,友盟里有,不过说一句,你导入的依赖包,如果是Push,那么就按照友盟的走,add,set都有,如果是PushSDK,那么就用上面的我那两个方法
https://developer.umeng.com/docs/67966/detail/89996?spm=a311a.9588098.0.0
到了这里,前端的处理基本上就完事了,剩下的就是后端的处理了,主要注意的是,后端的推送需要带入两个名称,进行推送,以及发送广播的类型
参考博客https://blog.csdn.net/Athena072213/article/details/83414743
Appkey:应用唯一标识。友盟消息推送服务提供的appkey和友盟统计分析平台使用的同一套appkey。
App Master Secret:服务器秘钥,用于服务器端调用API请求时对发送内容做签名验证。
Device Token:友盟消息推送服务对设备的唯一标识。Android的device_token是44位字符串,iOS的device_token是64位。
Alias:开发者自有账号,开发者可以在SDK中调用setAlias(alias, alias_type)接口将alias+alias_type与device_token做绑定,之后开发者就可以根据自有业务逻辑筛选出alias进行消息推送。
单播(unicast):向指定的设备发送消息。
列播(listcast):向指定的一批设备发送消息。
广播(broadcast):向安装该App的所有设备发送消息。
组播(groupcast)::向满足特定条件的设备集合发送消息,例如: “特定版本”、”特定地域”等。
文件播(filecast):开发者将批量的device_token或者alias存放到文件,通过文件ID进行消息发送。
自定义播(customizedcast):开发者通过自有的alias进行推送,可以针对单个或者一批alias进行推送,也可以将alias存放到文件进行发送。
后端的Android自定义广播示例
//android自定义播
/**
* 使用的是sdk的AndroidCustomizedcast对象
* object里面存放是android实际取的内容,其它参数是UM原定的可看业务而定
* setCustomField里面是android实际读取的,也可和移动端自定义数据结构
* 使用customizedcast.getPostBody()打印推送的内容
* 此处Alias = persionId || userId
* /
public void android() throws Exception{
String key = "585b2bd74543734be459bd001442";
String secret = "yoknur0n2iuqw543qjjoegyikbkj4aksej2";
//android自定义播
AndroidCustomizedcast customizedcast = new AndroidCustomizedcast(key, secret);
JSONObject result = new JSONObject();
JSONObject custom = new JSONObject();
JSONObject object = new JSONObject();
JSONArray array = new JSONArray();
object.put("sound", "todayTask");
object.put("messageTitle", "测试推送标题"); //推送标题
object.put("pushContent","测试推送的内容, android推送"); //推送内容
array.put(object);
result.put("arr0", array);
custom.put("result", result);
customizedcast.setCustomField(custom);
customizedcast.setAlias("1815", "SINA_WEIBO"); // 此处Alias = persionId || userId
customizedcast.setTicker("测试推送标题");
customizedcast.setTitle("测试推送标题");
customizedcast.setText("测试推送的内容, android推送");
customizedcast.setDisplayType(AndroidNotification.DisplayType.NOTIFICATION);
customizedcast.setProductionMode();
System.out.println("发送内容:"+customizedcast.getPostBody());
client.send(customizedcast);
}
如果无法接收到消息,那么可以用友盟进行发送测试
因为你设置别名了,所以需要选择特定用户,Alias只要你已经设置了别名,并启动了项目,那么点击之后会自己提示你已经上传的,选择你要用的就行,另外,并不是实时上传,可能有几分钟的延时搜不到,用户ID,就是第一个自己定义,只要不重复啥都行,能用来区分账户的名字,在设定好时间,就可以直接推送了
最后一步直接完成就行,然后就等着手机接收消息即可,接收到了,就可以跟后台进行对接了,如果后台发的消息你还是不能收到,友盟的能收到,那就是他的问题,可以查找一些示例进行修改。