移动推送Android SDK:透传消息+用户自建通知最佳实践

移动推送通知目前只能创建普通通知和标准视图的自定义样式通知,无法满足部分复杂的业务需求。如果您的App需要创建较为复杂的消息通知,建议使用移动推送透传消息,并在接收到消息后自行创建通知,本文为您提供移动推送SDK透传消息和自建通知的最佳实践。

1. 服务端推送透传消息

服务端推送时选择推送消息:

PushRequest pushRequest =new PushRequest();
// 推送目标
pushRequest.setAppKey(appKey);
pushRequest.setTarget("DEVICE");//推送目标: device:推送给设备; account:推送给指定账号,tag:推送给自定义标签; all: 推送给全部
pushRequest.setTargetValue("deviceId");//根据Target来设定,如Target=device, 则对应的值为设备id1,设备id2。多个值使用逗号分隔(账号与设备有一次最多100个的限制)。
pushRequest.setPushType("MESSAGE");// 消息类型 MESSAGE NOTICE
pushRequest.setDeviceType("ANDROID");// 设备类型 ANDROID iOS ALL.

// 推送配置
pushRequest.setTitle("ALi Push Title");// 消息的标题
pushRequest.setBody("Ali Push Body");// 消息的内容
......

2. 在onMessage回调中接收消息

透传消息会通过onMessage回调接口透出,可以在onMessage接口中创建通知。

/**
 * 推送消息的回调方法
 *
 * @param context
 * @param cPushMessage
 */
@Override
public void onMessage(Context context,CPushMessage cPushMessage){
  Log.e("MyMessageReceiver","onMessage, messageId: "+ cPushMessage.getMessageId()+", title: "+ cPushMessage.getTitle()+", content:"+ cPushMessage.getContent());
  buildNotification(context, cPushMessage);
}

3. 创建自建通知

创建自建通知可以参考以下代码:

/**
* 接受到对应消息后,消息的弹出处理
*/
public void buildNotification(Context context,CPushMessage message){
  NotificationManager notificationManager =(NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
  RemoteViews remoteViews =new RemoteViews(getPackageName(), R.layout.view_custom);
  remoteViews.setImageViewResource(R.id.custom_icon, R.mipmap.ic_launcher);
  remoteViews.setTextViewText(R.id.tv_custom_title, message.getTitle());
  remoteViews.setTextViewText(R.id.tv_custom_content, message.getContent());
  remoteViews.setTextViewText(R.id.tv_custom_time,newSimpleDateFormat("HH:mm").format(newDate()));
  //android 8.0 通知需要渠道Id
  Notification notification =new NotificationCompat.Builder(context,"channel_id")
		.setContent(remoteViews)
		.setContentTitle(message.getTitle())
		.setContentText(message.getContent())
		.setSmallIcon(R.mipmap.ic_launcher)
		.setDefaults(Notification.DEFAULT_VIBRATE)
		.setPriority(Notification.PRIORITY_DEFAULT)
		.build();
  String traceInfo = message.getTraceInfo();
  JSONObject json = new JSONObject(traceInfo);
  String bizJson = json.getString("biz");
  JSONObject taskIdJson = new JSONObject(bizJson);
  String taskId = taskIdJson.getString("taskId");
  String spitTaskId = taskId.substring(taskId.length() - 4);
  int notify=Integer.parseInt(spitTaskId);
  notification.contentIntent = buildClickContent(context, message,notify);
  notification.deleteIntent = buildDeleteContent(context, message,notify);
  notificationManager.notify(notify, notification);
}

public PendingIntent buildClickContent(Context context,CPushMessage message,int notify){
  Intent clickIntent = new Intent();
  clickIntent.setAction("your notification click action");
  //将message放入intent中,方便通知自建通知的点击事件
  clickIntent.putExtra("message key",  message);
  clickIntent.putExtra("notificationId", notify)
  return PendingIntent.getService(context, notify, clickIntent,PendingIntent.FLAG_UPDATE_CURRENT);
}

public PendingIntent buildDeleteContent(Context context,CPushMessage message,int notify){
  Intent deleteIntent = new Intent();
  deleteIntent.setAction("your notification click action");
  //将message放入intent中,方便通知自建通知的点击事件
  deleteIntent.putExtra("message key",  message);
  deleteIntent.putExtra("notificationId", notify)
  return PendingIntent.getService(context, clickNotificationCode, deleteIntent,PendingIntent.FLAG_UPDATE_CURRENT);
}

4. 创建通知点击/删除事件接收Service

在创建的通知被点击或删除时会分别触发对应的intent,发送给接收该intent的service。所以接下来需要创建接收对应事件的Service:

public class NotificationService extends Service{
  public staticfinalString TAG ="NotificationService";
  @Override
  public int onStartCommand(Intent intent,int flags,int startId){
    String action = intent.getAction();
    int notificationId = intent.getIntExtra("notificationId",0);
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    if(action.equals("your notification click action")){
      //获取message
      CPushMessage message = intent.getParcelableExtra("message key");
      //上报通知点击事件,点击事件相关信息可以在推送控制台查看到
      PushServiceFactory.getCloudPushService().clickMessage(message);
      //关闭通知栏
      notificationManager.cancel(notificationId);
    }else if(action.equals("your notification delete action")){
      //获取message
      CPushMessage message = intent.getParcelableExtra("message key");
      //上报通知删除事件,点击事件相关信息可以在推送控制台查看到
      PushServiceFactory.getCloudPushService().dismissMessage(message);
    }
  }
}

在AndroidManifest.xml文件中注册该Service:

<service
	android:name="NotificationService"
	android:exported="false">
	<intent-filter>
		<action android:name="your notification click action"/>
	</intent-filter>
	<intent-filter>
		<action android:name="your notification delete action"/>
	</intent-filter>
</service>

5. 注意事项

  • 如果需要将自建通知的删除/点击事件统计上报到阿里云推送控制台,必须完成以下几个步骤,具体代码可以参考上文:

    • onMessage回调透出的CPushMessage实例放到点击和删除事件intent中,CPushMessage实现了Parcelable接口,可以直接通过Intent.putExtra()方法添加。

    • 在通知点击/删除事件处理逻辑中先从intent获取到传入的CPushMessage实例,再调用CloudPushService.clickMessage/dismissMessage接口上报。

  • CloudPushService.clickMessage/dismissMessage对于一条消息重复上报存在事件覆盖,所以请确保一条消息只调用一次clickMessagedismissMessage接口。

  • 如果使用阿里云移动推送发送通知无需手动上报点击和删除事件。