在notification中设置PendingIntent
16lz
2021-01-26
在android屏幕的通知栏中增加notification,以显示mediaplayer控制面板
点击控制面板的按钮将发送intent来控制mediaplayer
这些intent将以PendingIntent的形式绑定到控制面板上的按钮上
不能工作的代码:
public void sendNotification(int status) { if (playingFile != null) { /** * 给notification构建intent */ //如下是在notification中给remoteview设置PendingIntent //receiver按NOTIFICATION_ACTION进行过滤 //过滤之后按putExtra中设置的参数分辨命令 // //陷阱是setAction()和PendingIntent.getBroadcast()以及FLAG_UPDATE_CURRENT //如下代码,最终所有PendingIntent都会变成最后一个! //猜测,无论从上到下生成多少个PendingIntent //但同一条ACTION的PendingIntent.getBroadcast()背后只对应一个静态变量! //也即这四个实际上是一个PendingIntent //FLAG_UPDATE_CURRENT及另外几个参数的说明也非常不易懂,看得很晕 // //解决方案是,设置receiver可以过滤出多条ACTION而不是一条 //不按putExtra里面设置的数据进行分辨 //而是直接根据不同的ACTION来分辨命令 //可以工作的代码在后面 Intent resultIntentLast = new Intent(this, PlayService.class); resultIntentLast.setAction(LocalConst.NOTIFICATION_ACTION); resultIntentLast.putExtra(LocalConst.NOTIFICATION_OP, LocalConst.op_last); PendingIntent pendingIntentLast = PendingIntent.getBroadcast(this, 0, resultIntentLast, PendingIntent.FLAG_UPDATE_CURRENT); Intent resultIntentNext = new Intent(this, PlayService.class); resultIntentNext.setAction(LocalConst.NOTIFICATION_ACTION); resultIntentLast.putExtra(LocalConst.NOTIFICATION_OP, LocalConst.op_next); PendingIntent pendingIntentNext = PendingIntent.getBroadcast(this, 0, resultIntentNext, PendingIntent.FLAG_UPDATE_CURRENT); Intent resultIntentPlay = new Intent(this, PlayService.class); resultIntentPlay.setAction(LocalConst.NOTIFICATION_ACTION); resultIntentLast.putExtra(LocalConst.NOTIFICATION_OP, LocalConst.op_play); PendingIntent pendingIntentPlay = PendingIntent.getBroadcast(this, 0, resultIntentPlay, PendingIntent.FLAG_UPDATE_CURRENT); Intent resultIntentPause = new Intent(this, PlayService.class); resultIntentPause.setAction(LocalConst.NOTIFICATION_ACTION); resultIntentLast.putExtra(LocalConst.NOTIFICATION_OP, LocalConst.op_pause); PendingIntent pendingIntentPause = PendingIntent.getBroadcast(this, 0, resultIntentPause, PendingIntent.FLAG_UPDATE_CURRENT); /** * 给notification构建remoteView */ RemoteViews notifyView = new RemoteViews(this.getPackageName(), R.layout.notification); notifyView.setTextViewText(R.id.notification_name, playingFile.getName()); notifyView.setImageViewResource(R.id.notification_icon, R.drawable.icon); notifyView.setOnClickPendingIntent(R.id.notification_b1, pendingIntentLast); notifyView.setOnClickPendingIntent(R.id.notification_b2, pendingIntentNext); notifyView.setOnClickPendingIntent(R.id.notification_b3, pendingIntentPlay); notifyView.setOnClickPendingIntent(R.id.notification_b4, pendingIntentPause); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.bottom) .setContentTitle(playingFile.getName()) .setContentText(getResources().getString(R.string.notification_back_msg)) //这是另外一个陷阱 //上面三个设置是不显示的,但是仅仅设置remoteView是不够的 //得有前面三个设置(或许部分设置),否则不能显示notification .setContent(notifyView); Intent resultIntent = new Intent(this, DirPlayerActivity.class); PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); // Sets an ID for the notification int mNotificationId = 001; // Gets an instance of the NotificationManager service NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); // Builds the notification and issues it. mNotifyMgr.notify(mNotificationId, mBuilder.build()); }}
可以工作的代码:
public void sendNotification(int status) { if (playingFile != null) { /** * 给notification构建remoteView */ RemoteViews notifyView = new RemoteViews(this.getPackageName(), R.layout.notification); notifyView.setTextViewText(R.id.notification_name, playingFile.getName()); notifyView.setImageViewResource(R.id.notification_icon, R.drawable.icon); //采用多条ACTION并且精简后的代码 notifyView.setOnClickPendingIntent(R.id.notification_goto_pause, PendingIntent.getBroadcast(this, 0, new Intent(LocalConst.NOTIFICATION_GOTO_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT)); notifyView.setOnClickPendingIntent(R.id.notification_goto_last, PendingIntent.getBroadcast(this, 0, new Intent(LocalConst.NOTIFICATION_GOTO_LAST), PendingIntent.FLAG_UPDATE_CURRENT)); notifyView.setOnClickPendingIntent(R.id.notification_goto_next, PendingIntent.getBroadcast(this, 0, new Intent(LocalConst.NOTIFICATION_GOTO_NEXT), PendingIntent.FLAG_UPDATE_CURRENT)); notifyView.setOnClickPendingIntent(R.id.notification_goto_play, PendingIntent.getBroadcast(this, 0, new Intent(LocalConst.NOTIFICATION_GOTO_PLAY), PendingIntent.FLAG_UPDATE_CURRENT)); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.bottom) .setContentTitle(playingFile.getName()) .setContentText(getResources().getString(R.string.notification_back_msg)) /** * 非常奇怪,上面三个set不能省略,否则notification就不显示 * 但上面三项并不显示,因为使用了remoteView及其布局 */ .setContent(notifyView); Intent resultIntent = new Intent(this, DirPlayerActivity.class); PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); // Sets an ID for the notification int mNotificationId = 001; // Gets an instance of the NotificationManager service NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); // Builds the notification and issues it. mNotifyMgr.notify(mNotificationId, mBuilder.build()); }}
最后一个陷阱是注册receiver不能使用LocalBroadcastManager
因为notification不在app进程之中
如下代码不能工作
/** * notification上面的按键将发送intent给service * notification上面其他部分被点击后发送pendingIntent给activity */ IntentFilter mNotificationIntentFilter = new IntentFilter( LocalConst.NOTIFICATION_ACTION); mNotificationInforReceiver = new NotificationInforReceiver(); // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this).registerReceiver( mNotificationInforReceiver, mNotificationIntentFilter);
直接调用registerReceiver才能工作
/** * notification上面的按键将发送intent给service * notification上面其他部分被点击后发送pendingIntent给activity */ IntentFilter mNotificationIntentFilter = new IntentFilter(); mNotificationIntentFilter.addAction(LocalConst.NOTIFICATION_GOTO_LAST); mNotificationIntentFilter.addAction(LocalConst.NOTIFICATION_GOTO_NEXT); mNotificationIntentFilter.addAction(LocalConst.NOTIFICATION_GOTO_PLAY); mNotificationIntentFilter.addAction(LocalConst.NOTIFICATION_GOTO_PAUSE); mNotificationInforReceiver = new NotificationInforReceiver(); /** * 注意,使用LocalBroadcastManager注册的receiver只能接收本app内部的intent * 但notification在本app之外 * 所以这里需要直接使用registerReceiver来注册 */ registerReceiver( mNotificationInforReceiver, mNotificationIntentFilter);
更多相关文章
- Android(安卓)自定义View(二)函数分析
- Android(安卓)单例模式与SharedPreferences一起使用
- Android(安卓)应用开发笔记 - 下拉列表(Spinner)
- AttachCurrentThread报错
- Android(安卓)premission 访问权限代码
- dalvik.vm 属性与android:largeHeap
- Android(安卓)Studio jcenter集成butterknife:8.x.0
- Android(安卓)使用Socket实现服务器与手机客户端的长连接四:使用
- Android项目中使用javacv和javacpp的代码混淆配置