监听自定义的通知栏是否被点击了

如何知道通知栏的展示的 Notification 被点击了?

在某些业务需求下,我们需要知道用户是否点击了通知栏,但是察看 Notifycation 和 NotifycationManager 里面都没有相关方法来设置点击监听器!

那怎么办?


Notifycation 本来就需要我们给他设置一个 Intent 来执行点击之后的动作,这个 Intent 通过 PendingIntent 赋予。


关于 PendingIntent 刚接触可能会觉得不理解,官方解释:A description of an Intent and target action to perform with it. 即将要执行的动作

我们先从区别上来看他们:

    1.普通的 Intent 我们发出去之后立马就执行了,比如 startActivity(new Intent(Intent.ACTION_VIEW, Uri.parser("http://baidu.com"))) 之后立马就跳到浏览器打开百度首页了

    2.Notifycation 发出去之后用户什么时候点击是不确定的,我们先将点击之后要执行的 Intent 保存下来,等到用户点击之后在取出来执行,那用什么来保存 Intent 呢?PendingIntent(注:我这里为了方便理解而这样解释,事实上 PendingIntent 远比保存 Intent 复杂,涉及跨进程)


而,Intent 本身实现了 Parcelable 接口,可以用来跨进程传输,所以我们可以通过 Intent.putExtra("name", intemt) 将真正要执行的 Intent 保存在 clickIntent 对象里!

// 自定义显示的通知 ,创建RemoteView对象
	private synchronized void showCustomizeNotification(Context context,
			String contentTitle, String contentText, Intent intent, int type) {
		int icon = R.drawable.ic_launcher;
		long when = new Date().getTime() / 1000;
		Notification noti = new Notification(icon, contentTitle, when);
		noti.flags = Notification.FLAG_AUTO_CANCEL;
		noti.defaults = Notification.DEFAULT_ALL;// 开启铃声
		// 1、创建一个自定义的消息布局 view.xml
		// 2、在程序代码中使用RemoteViews的方法来定义image和text。然后把RemoteViews对象传到contentView字段
		RemoteViews remoteView = new RemoteViews(context.getPackageName(),
				R.layout.notification);
		remoteView.setImageViewResource(R.id.notification_img,
				R.drawable.ic_launcher);
		remoteView.setTextViewText(R.id.notification_title, contentTitle);
		remoteView.setTextViewText(R.id.notification_txt, contentText);
		remoteView.setTextViewText(R.id.notification_time,
				getTime(String.valueOf(when)));

		noti.contentView = remoteView;
		// 3、为Notification的contentIntent字段定义一个Intent(注意,使用自定义View不需要setLatestEventInfo()方法)
		Intent clickIntent = new Intent();
		clickIntent.setClass(context, ClickReceiver.class);
		clickIntent.putExtra("realIntent", intent);  
		PendingIntent contentIntent = PendingIntent.getBroadcast(context, type,
				clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		noti.contentIntent = contentIntent;
		NotificationManager mnotiManager = (NotificationManager) context
				.getSystemService(Context.NOTIFICATION_SERVICE);
		mnotiManager.notify(type, noti);
		// Intent mIntent = new Intent(AppContext.REMOVE_WARN_RECORD);
		// sendStickyBroadcast(mIntent);

	}
当用户点击 Notifycation 之后,系统调用 ClickReceiver 的 onReceiver() 方法,你在此时执行真正的点击逻辑就OK,看码:

import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class ClickReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		
		NotificationManager notificationManager = (NotificationManager) context
				.getSystemService(Context.NOTIFICATION_SERVICE);
		notificationManager.cancelAll();
		Intent realIntent = intent.getParcelableExtra("realIntent");  
	    context.startActivity(realIntent);  
	}

}

1.千万注意别忘记了广播在androidmainfest.xml中注册

2.在 onReceiver 的 context 直接启动 Activity 是会报错的,需要给 Intent 加上 Intent.FLAG_ACTIVITY_NEW_TASK 标志!



你可能感兴趣的:(android技术)