这是一份详细集成友盟推送SDK的心酸历程,也集成了华为、小米、OPPO、vivo厂商通道,处理了app进程关闭、app在后台、app前台通知点击的处理
1 根据友盟自动集成文档,集成友盟SDK 友盟地址 点击这里
2 集成后查看友盟demo,进行预初始化那些,打印友盟token等
3 使用友盟的推送工具测试集成是否OK
以上这三步最简单,就不多说了。
重点来了:
1 友盟的自定义点击通知时的打开动作 UmengNotificationClickHandler
UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {
@Override
public void dealWithCustomAction(Context context, UMessage msg) {
super.dealWithCustomAction(context, msg);
Log.i(TAG, "dealWithCustomAction: " + msg.getRaw().toString());
}
@Override
public void openActivity(Context context, UMessage msg) {
super.openActivity(context, msg);
Log.i(TAG, "click openActivity: " + msg.getRaw().toString());
}
@Override
public void launchApp(Context context, UMessage msg) {
super.launchApp(context, msg);
Log.i(TAG, "click launchApp: " + msg.getRaw().toString());
}
@Override
public void dismissNotification(Context context, UMessage msg) {
super.dismissNotification(context, msg);
Log.i(TAG, "click dismissNotification: " + msg.getRaw().toString());
}
};
pushAgent.setNotificationClickHandler(notificationClickHandler);
这个自定义只有在app位于前台的时候有作用,很多机型在app home回桌面后就没有反应了,所以用这个不好。如果你要用这个,那么在通知类型为自定义的时候(大多时候通知都为自定义,然后根据参数进行跳转),那么dealWithCustomAction()这个方法中,你的自定义处理需要写在super方法之前,不然没反应。
下面我将正确的处理方法:
1 集成厂商通道,集成的方法根据友盟的文档就可以了,比各大厂商自己的文档简单多了,集成后不要看友盟文档里面说的日志,自己调方法打印regId就可以了,有了regId 然后用各大厂商的推送测试工具,测试app关闭的情况下,能否收到通知。这个各大厂商里面都有的,小米、OPPO等有申请一下通道ID,不然小米会给你整一个不重要通知里面,看不懂通知了。这里再讲一个大坑,vivo的厂商推送,一天一个设备只有5个机会,5次完了后就收不到了,然后推送的标题和消息里面不能加 测试 test这样的文字,不然一样收不到
2 根据友盟给的文档,创建一个用于接受厂商通道消息的activity
public class MfrMessageActivity extends UmengNotifyClickActivity {
private static final String TAG = "MfrMessageActivity";
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_push);
}
@Override
public void onMessage(Intent intent) {
super.onMessage(intent);
Bundle bundle = intent.getExtras();
if (bundle != null) {
Log.d(TAG, "bundle: " + bundle);
}
String body = intent.getStringExtra(AgooConstants.MESSAGE_BODY);
Log.d(TAG, "body: " + body);
if (!TextUtils.isEmpty(body)) {
runOnUiThread(() -> ((TextView) findViewById(R.id.tv)).setText(body));
}
}
}
所有的厂商通道推送的离线消息,都在这里处理,点击消息的时候,会调用这里的onMessage方法,拿到里面的body信息,然后再打开app传递进去就可以了,这个可以设置这个Activity和splash一样的主题,不然打开app初始化的时候是白屏的。
OK 以上就是app离线时消息的处理
下面再说app位于后台时候的处理,上面我们讲到了不行的例子,打开友盟Demo,里面有这样的设置
pushAgent.setPushIntentServiceClass(MyCustomMessageService.class);
找到这个MyCustomMessageService,直接复制,记住SDK要最新版本,不然会报错的
public class MyCustomMessageService extends UmengMessageService {
private static final String TAG = "MyCustomMessageService";
private Context context;
@Override
public void onMessage(Context context, Intent intent) {
this.context = context;
Log.i(TAG, "onMessage");
try {
String body = intent.getStringExtra(AgooConstants.MESSAGE_BODY);
UMessage message = new UMessage(new JSONObject(body));
if (UMessage.DISPLAY_TYPE_NOTIFICATION.equals(message.display_type)) {
//处理通知消息
handleNotificationMessage(message);
} else if (UMessage.DISPLAY_TYPE_CUSTOM.equals(message.display_type)) {
//TODO: 处理自定义消息
handleCustomMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void handleCustomMessage(UMessage message) {
}
private void handleNotificationMessage(UMessage msg) {
Notification.Builder builder;
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = UPushNotificationChannel.PRIMARY_CHANNEL;
String channelName = PushAgent.getInstance(this).getNotificationChannelName();
NotificationChannel channel = manager.getNotificationChannel(channelId);
if (channel == null) {
channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
manager.createNotificationChannel(channel);
}
builder = new Notification.Builder(this, UPushNotificationChannel.PRIMARY_CHANNEL);
} else {
builder = new Notification.Builder(this);
}
builder.setContentTitle(msg.title)
.setContentText(msg.text)
.setTicker(msg.ticker)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.umeng_push_notification_default_small_icon)
.setAutoCancel(true);
Notification notification = builder.getNotification();
PendingIntent clickIntent = getClickPendingIntent(this, msg);
notification.deleteIntent = getDismissPendingIntent(this, msg);
notification.contentIntent = clickIntent;
manager.notify((int) SystemClock.elapsedRealtime(), notification);
UTrack.getInstance().trackMsgShow(msg, notification);
}
public PendingIntent getClickPendingIntent(Context context, UMessage msg) {
Intent intent = new Intent(context, MyCustomNotificationClickActivity.class);
intent.setPackage(context.getPackageName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(MyCustomNotificationClickActivity.EXTRA_BODY, msg.getRaw().toString());
int flags = PendingIntent.FLAG_CANCEL_CURRENT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
flags |= PendingIntent.FLAG_IMMUTABLE;
}
return PendingIntent.getActivity(context, (int) (System.currentTimeMillis()), intent, flags);
}
public PendingIntent getDismissPendingIntent(Context context, UMessage msg) {
return new UmengMessageHandler().getDismissPendingIntent(context, msg);
}
}
getClickPendingIntent方法里面有个 MyCustomNotificationClickActivity
这个activity在app位于后台时候消息点击,也能接受到点击事件
public class MyCustomNotificationClickActivity extends Activity {
public static final String EXTRA_BODY = "body";
private static final String TAG = "MyCustomMessageService";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null) {
String body = intent.getStringExtra(EXTRA_BODY);
// LogCook.i(XiYaYaApplicationLike.TAG,"测试日志i MyCustomNotificationClickActivity" + body);
// LogCook.i(XiYaYaApplicationLike.TAG,"测试日志i XiYaYaApplicationLike.haveActivity" + XiYaYaApplicationLike.haveActivity);
if (body != null) {
try {
UMessage message = new UMessage(new JSONObject(body));
UTrack.getInstance().trackMsgClick(message);
//TODO: 处理通知消息
if (XiYaYaApplicationLike.haveActivity > 1){
MessageBean messageBean = new Gson().fromJson(body, MessageBean.class);
if ("go_custom".equals(messageBean.getBody().getAfter_open())){
// 自定义行为
PushMessageClick.customMessageClick(MainActivity.gson,messageBean.getBody().getCustom(),this);
}else if ("go_activity".equals(messageBean.getBody().getAfter_open())){
// 打开指定Ac
PushMessageClick.openAcMessageClick(MainActivity.gson,messageBean.getBody().getActivity(),messageBean.getExtra(),this);
}
// new UmengNotificationClickHandler().handleMessage(this, message);
}else {
Intent intent1 = new Intent(this, SplashActivity.class);
intent1.putExtra("messagebody",body);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
finish();
}
}
这个地方,就能处理app活着时候的所有消息点击的处理,这样app活着有这个Ac,app关闭了有厂商通道的Ac,所有的消息点击都能处理了。
注:离线消息一般要几分钟才能收到,
然后app要设置关闭推送的按钮,不然应用市场不给过。这些友盟文档都有的。