做手机控车项目,需求是车在遭受非法侵入的时候要及时报警,之前是用短信的方式,一开始量少还可以,随着用户越来越多,短信的开销越来越大,决定做成推送方式,这就要求客户一定能够收到推送,无论后台进程是否被杀死.
首先登陆阿里云官方平台,创建应用 阿里云创建应用
然后就是下载各种包配置应用,有maven库快速集成方式,但我不知道为什么下载不下来,所以还是选择了手动配置,以下是用到的包
配置appkey和appsecret(创建应用时候生成的)
清单文件里增加权限和注册service和receiver
手动创建消息接收Receiver,继承自com.alibaba.sdk.android.push.MessageReceiver,并在对应回调中添加业务处理逻辑
public class MyMessageReceiver extends MessageReceiver {
// 消息接收部分的LOG_TAG
public static final String REC_TAG = "receiver";
@Override
public void onNotification(Context context, String title, String summary, Map extraMap) {
// TODO 处理推送通知
Log.e("MyMessageReceiver", "Receive notification, title: " + title + ", summary: " + summary + ", extraMap: " + extraMap);
}
@Override
public void onMessage(Context context, CPushMessage cPushMessage) {
Log.e("MyMessageReceiver", "onMessage, messageId: " + cPushMessage.getMessageId() + ", title: " + cPushMessage.getTitle() + ", content:" + cPushMessage.getContent());
}
@Override
public void onNotificationOpened(Context context, String title, String summary, String extraMap) {
Log.e("MyMessageReceiver", "onNotificationOpened, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
}
@Override
protected void onNotificationClickedWithNoAction(Context context, String title, String summary, String extraMap) {
Log.e("MyMessageReceiver", "onNotificationClickedWithNoAction, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
}
@Override
protected void onNotificationReceivedInApp(Context context, String title, String summary, Map extraMap, int openType, String openActivity, String openUrl) {
Log.e("MyMessageReceiver", "onNotificationReceivedInApp, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap + ", openType:" + openType + ", openActivity:" + openActivity + ", openUrl:" + openUrl);
}
@Override
protected void onNotificationRemoved(Context context, String messageId) {
Log.e("MyMessageReceiver", "onNotificationRemoved");
}
}
并在清单文件中配置该receiver
然后官方文档里有这样一句提示
如果是从V2.3.7及以下版本升级到V3.0.0及以上版本的用户,需将
改为
,否则会接收不到推送。
虽然我不是这样的用户,但还是做了修改
然后再application里初始化推送通道(此处考虑了8.0以上限制推送的情况:即定义了一个通知渠道的id)
/**
* 初始化云推送通道
* @param applicationContext
*/
private void initCloudChannel(Context applicationContext) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
// 通知渠道的id
String id = "1";
// 用户可以看到的通知渠道的名字.
CharSequence name = "notification channel";
// 用户可以看到的通知渠道的描述
String description = "notification description";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// // 设置渠道描述
// mChannel.setDescription("测试通知组");
// // 是否绕过请勿打扰模式
mChannel.canBypassDnd();
// // 设置绕过请勿打扰模式
mChannel.setBypassDnd(true);
// // 桌面Launcher的消息角标
mChannel.canShowBadge();
// // 设置显示桌面Launcher的消息角标
mChannel.setShowBadge(true);
// // 设置通知出现时声音,默认通知是有声音的
// mChannel.setSound(null, null);
// // 设置通知出现时的闪灯(如果 android 设备支持的话)
// mChannel.enableLights(true);
// mChannel.setLightColor(Color.RED);
// // 设置通知出现时的震动(如果 android 设备支持的话)
// mChannel.enableVibration(true);
// 配置通知渠道的属性
mChannel.setDescription(description);
// 设置通知出现时的闪灯(如果 android 设备支持的话)
mChannel.enableLights(true);
mChannel.setLightColor(Color.RED);
// 设置通知出现时的震动(如果 android 设备支持的话)
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
//最后在notificationmanager中创建该通知渠道
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(mChannel);
}
}
// AdvancedCustomPushNotification notification = new AdvancedCustomPushNotification(R.layout.notitfication_layout, R.id.m_icon, R.id.m_title, R.id.m_text);
// notification.setServerOptionFirst(true);
// notification.setBuildWhenAppInForeground(true);
// notification.setRemindType(BasicCustomPushNotification.REMIND_TYPE_VIBRATE_AND_SOUND);
// boolean res = CustomNotificationBuilder.getInstance().setCustomNotification(2, notification);
PushServiceFactory.init(applicationContext);
pushService = PushServiceFactory.getCloudPushService();
pushService.register(applicationContext, new CommonCallback() {
@Override
public void onSuccess(String response) {
Log.d("MyMessageReceiver", "init cloudchannel success"+response+ pushService.getDeviceId());
}
@Override
public void onFailed(String errorCode, String errorMessage) {
Log.d("MyMessageReceiver", "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage);
}
});
}
至此,就可以在控制台测试阿里云推送了
接下来才是重点
以上操作只能保证APP开启或者进程在后台运行的情况下才能收到推送(有时候后台运行也收不到),在后台进程被杀死的情况下,是不能收到推送的,好在阿里云提供的有移动推送辅助通道,这个东西,个人理解就是阿里云与各个手机厂商的合作,需要去各个手机厂商的开发平台去申请,申请成功就相当于借用厂商通道向厂商自己制造的手机发送通知,这样就不再受进程限制
那就要一个一个来:辅助通道配置
一:华为
首先在华为开发者联盟注册APP,得到APPID和APPsecret,并开启push功能 开启push服务
下载辅助通道扩展包 阿里云maven库地址,可搜索并下载扩展包 这里其实可以直接连接maven库,很不幸,我还是不能从maven中取包,所以只能手动集成
另外阿里云官方文档里添加的辅助推送扩展包依赖是3.0.10版本,但maven里最新的只有3.0.9版本
这里很矛盾,暂且不问(至于他说的OPPO,vivo需使用3.0.10版本,鉴于本人在写这篇文章时只做了华为,所以先搁置,车到山前必有路,做到了再说)
项目里添加华为推送sdk依赖:
dependencies {
......
compile 'com.aliyun.ams:huawei-push:2.6.3.305'
compile 'com.aliyun.ams:huawei-push-base:2.6.3.305'
}
同时在AndroidManifest文件中添加如下配置:
在application.onCreate()方法中初始化厂商通道. 注意:辅助通道注册务必在Application中执行且放在推送SDK初始化代码之后,否则可能导致辅助通道注册失败
// 注册方法会自动判断是否支持小米系统推送,如不支持会跳过注册。
MiPushRegister.register(applicationContext, "小米AppID", "小米AppKey");
// 注册方法会自动判断是否支持华为系统推送,如不支持会跳过注册。
HuaWeiRegister.register(application);
//GCM/FCM辅助通道注册
GcmRegister.register(this, sendId, applicationId); //sendId/applicationId为步骤获得的参数
// OPPO通道注册
OppoRegister.register(applicationContext, appKey, appSecret); // appKey/appSecret在OPPO开发者平台获取
// 魅族通道注册
MeizuRegister.register(applicationContext, "appId", "appkey"); // appId/appkey在魅族开发者平台获取
// VIVO通道注册
VivoRegister.register(applicationContext);
如不成功,检查是否在华为控制台配置SHA256指纹证书,目前华为需要配置 生成并配置指纹证书
这里我一开始初始化失败了,配置指纹证书之后就成功了
通过辅助通道(厂商通道)送达的通知,要定义一个activity去接收数据:官方文档如下:
AndroidPopupActivity
(MiPushSystemNotificationActivity
已废弃,小米、华为、OPPO等厂商通道弹窗统一继承AndroidPopupActivity
),否则无法获取到通知的相关信息,并且会影响通知到达率的统计;AndroidPopupActivity
中提供抽象方法onSysNoticeOpened()
,实现该方法后可获取到辅助弹窗通知的标题
、内容
和额外参数
,在通知点击时触发,原本的通知回调onNotification()
和onNotificationOpened()
不适用于辅助弹窗;指定打开的托管弹窗Activity在AndroidManifest.xml中注册时需要声明属性:android:exported=true
import com.alibaba.sdk.android.push.AndroidPopupActivity;
public class PopupPushActivity extends AndroidPopupActivity {
static final String TAG = "PopupPushActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* 实现通知打开回调方法,获取通知相关信息
* @param title 标题
* @param summary 内容
* @param extMap 额外参数
*/
@Override
protected void onSysNoticeOpened(String title, String summary, Map extMap) {
Log.d("OnMiPushSysNoticeOpened, title: " + title + ", content: " + summary + ", extMap: " + extMap);
}
}
服务端在推送时,需自己配置好appkey和appsecret,还要置顶辅助弹框对应的activity
至此,华为手机上的app无论后台进程存在与否,都能收到推送
其他手机厂商也差不多都是这样的流程,等我做完了,哪个有特别需要注意的地方,再来更新