极光推送提供三种方法实现Notification通知
- 三方开发平台发送普通消息,客户端设置PushNotificationBuilder,实现基础的Notification通知
- 三方开放平台发送普通消息,客户端设置CustomPushNotificationBuilder,实现高级自定义的Notification通知
- 三方开放平台发送自定义消息,客户端默认不处理此类消息,客户端定义Receiver接收自定义消息并进行处理
- 使用普通内容为空,将普通消息转成自定义消息类型,进而达到所需效果
但是前三种方案无法实现自定义声音,只有第四种方案可实现自定义Notification并进行通知
尝试方案一:
思路:接收三方开放平台自定义消息,自定义Notification更改提示音
AndroidManifest.xml
<receiver android:name=".application.MyReceiver" android:enabled="true"> <intent-filter > <!-- Required 用户注册SDK的intent --> <action android:name="cn.jpush.android.intent.REGISTRATION" /> <!-- Required 用户接收SDK消息的intent --> <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" /> <!-- Required 用户接收SDK通知栏信息的intent --> <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" /> <!-- Required 用户打开自定义通知栏的intent --> <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" /> <!-- Optional 用户接受Rich Push Javascript 回调函数的intent --> <action android:name="cn.jpush.android.intent.ACTION_RICHPUSH_CALLBACK" /> <!-- 接收网络变化 连接/断开 since 1.6.3 --> <action android:name="cn.jpush.android.intent.CONNECTION" /> <category android:name="应用包名" /> </intent-filter> </receiver>
MyReceiver.java
public class MyReceiver extends BroadcastReceiver { private static final String TAG = MyReceiver.class.getSimpleName(); private static final int NOTIFICATION_SHOW_SHOW_AT_MOST = 3; //推送通知最多显示条数 @Override public void onReceive(Context context, Intent intent) { Bundle bundle =intent.getExtras(); // if(intent.getAction().equals(JPushInterface.ACTION_NOTIFICATION_RECEIVED)){ Log.i(TAG, "接收到了通知"); String title=bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE); String content=bundle.getString(JPushInterface.EXTRA_ALERT); String extra=bundle.getString(JPushInterface.EXTRA_EXTRA); Log.i(TAG, "标题:【"+title+"】,内容:【"+content+"】,附加参数:【"+extra+"】"); }else if(intent.getAction().equals(JPushInterface.ACTION_MESSAGE_RECEIVED)){ Log.i(TAG, "接收到了消息"); String message =bundle.getString(JPushInterface.EXTRA_MESSAGE); processCustomMessage(context, bundle); Log.i(TAG, "接收到的消息是:【"+message+"】"); }else if(intent.getAction().equals(JPushInterface.ACTION_NOTIFICATION_OPENED)){ Log.i(TAG, "用户正在打开通知"); } } /** * 实现自定义推送声音 * @param context * @param bundle */ private void processCustomMessage(Context context, Bundle bundle) { NotificationCompat.Builder notification = new NotificationCompat.Builder(context); String title = bundle.getString(JPushInterface.EXTRA_TITLE); String msg = bundle.getString(JPushInterface.EXTRA_MESSAGE); String extras = bundle.getString(JPushInterface.EXTRA_EXTRA); Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.icon_mdpi); Intent mIntent = new Intent(context,****.class); mIntent.putExtras(bundle); mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, mIntent, 0); notification.setContentIntent(pendingIntent) .setAutoCancel(true) .setContentText(msg) .setContentTitle(title.equals("") ? "title": title) .setSmallIcon(R.mipmap.icon_mdpi) .setLargeIcon(bitmap) .setNumber(NOTIFICATION_SHOW_SHOW_AT_MOST); Log.e(TAG, "processCustomMessage: extras----->" + extras); if (!TextUtils.isEmpty(extras)) { try { JSONObject extraJson = new JSONObject(extras); if (null != extraJson && extraJson.length() > 0) { String sound = extraJson.getString("sound"); if("1".equals(sound)){ notification.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/" +R.raw.default_push_sound)); } else { notification.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/" +R.raw.test)); } } } catch (JSONException e) { e.printStackTrace(); } } NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); notificationManager.notify(NOTIFICATION_SHOW_SHOW_AT_MOST, notification.build()); //id随意,正好使用定义的常量做id,0除外,0为默认的Notification } }
效果实现了,跟服务端沟通,发现只有开发平台上有自定义消息,服务端没自定义消息的api接口,烦唷!!!
尝试方案二:
思路:查看接口文档,发现极光推送采用Receiver接收普通消息和自定义消息,通过拦截广播,不让极光三方库处理默认的Notification
查看极光AndroidManifst.xml的PushReceiver配置
<!-- Required SDK核心功能 --> <receiver android:name="cn.jpush.android.service.PushReceiver" android:enabled="true"> <intent-filter android:priority="1000"> <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" /> <!-- Required 显示通知栏 --> <category android:name="应用包名" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.USER_PRESENT" /> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> <!-- Optional --> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED" /> <action android:name="android.intent.action.PACKAGE_REMOVED" /> <data android:scheme="应用包名" /> </intent-filter> </receiver>
发现极光推送通过PushReceiver来代理接收派发普通消息和自定义消息。那我就利用MyReceiver,而且优先级为65535,保证最先接收到消息 在MyReceiver中普通消息过滤中添加abortBroadcast(); 吸收广播,禁止往下传递广播,运行后提示“BroadcastReceiver trying to return result during a non-ordered broadcast”,居然是无序广播。。。 这。。。。极光你就不能给个活路么
尝试方案三:
思路:不让我自定义,那我就把默认的铃声去掉,然后在接收到普通消息广播之后使用SoundPool播放提示音乐
init JPush之后 BasicPushNotificationBuilder builder = new BasicPushNotificationBuilder(this); builder.notificationDefaults = Notification.DEFAULT_LIGHTS; builder.statusBarDrawable = R.drawable.icon_mdpi; builder.notificationFlags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS; JPushInterface.setPushNotificationBuilder(1, builder);
notificationDefaults 是通过设置二进制位来判断的,DEFAULT_SOUND=1 使用红米Note4做测试,还是会有提示音。。 不想做了。。。
尝试方案四:
思路:查看文档时无意间发现,当普通通知内容为空,将不执行默认的Notification,使用extra传递Notification.title和Notification.msg,再接收到普通消息之后执行之前实现的自定义processCustomMessage方法
接受广播
如果全部类型的广播都接收,则需要在 AndroidManifest.xml 里添加如下的配置信息: <receiver android:name="Your Receiver" android:enabled="true"> <intent-filter> <action android:name="cn.jpush.android.intent.REGISTRATION" /> <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" /> <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" /> <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" /> <action android:name="cn.jpush.android.intent.NOTIFICATION_CLICK_ACTION" /> <action android:name="cn.jpush.android.intent.CONNECTION" /> <category android:name="You package Name" /> </intent-filter> </receiver>
Action - JPushInterface.ACTION_NOTIFICATION_RECEIVED.
字符串值 "cn.jpush.android.intent.NOTIFICATION_RECEIVED" 功能描述: 收到了通知 Push。 如果通知的内容为空,则在通知栏上不会展示通知。 但是,这个广播 Intent 还是会有。开发者可以取到通知内容外的其他信息。
终于搞定了,再也不想用极光,好麻烦-。-