android开发之notification通知完全解析

android开发之notification通知完全解析


本文主要介绍的是notification通知的使用,通过阅读此文,你可以了解,在android开发中,notification通知各种使用方法。本文的notification主要是针对android4.4以下的版本。

现在,我们来看一下,如何实现一个notification。估计大家现在最常用的做法是下面这种:

 Notification notification = new Notification(R.drawable.ic_launcher, 
 getText(R.string.app_name),
			System.currentTimeMillis());

	Intent notificationIntent = new Intent(this, MyService.class);
	PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, 
	notificationIntent, 0);
	notification.setLatestEventInfo(this, getText(R.string.hello_world),
			getText(R.string.hello_world), pendingIntent);
	startForeground(1, notification);

这是在service里面启动一个notification,但是大家一定记住这种方法已经过时了,也就是说Google官方已经不提倡使用这种方法来启动一个notification了。官方推荐使用V4包下NotificationCompat.Builder,这样,我们便可以设置各种属性。

好了,现在我们具体来看一下,Notification的具体实现。


1.创建一个简单的notification

Required notification contents
notification必须要包含的内容

A Notification object must contain the following:
一个notification必须包含下面的属性:

A small icon, set by setSmallIcon()
一个small icon,用setSmallIcon()来设置,对应于上图中的2号区域

A title, set by setContentTitle()
一个title,用setContentTitle()来设置,对应于上图中的1号区域

Detail text, set by setContentText()
详细文本,用setContentText()来设置,对应于上图中的3号区域

这三个是必须设置的,至于其他的扩展则是需求而定。代码如下:

private NotificationManager manager;

NotificationCompat.Builder notifyBuilder;

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);

	/*实例化NotificationManager以获取系统服务*/
	manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

}

/**
 * 显示最简单的通知,以下method中的三个set方法是必须设置的
 *
 * @param view
 */
public void simNotification(View view) {

	Toast.makeText(this, "hha", Toast.LENGTH_LONG).show();

	notifyBuilder = new NotificationCompat.Builder(this)
			/*设置small icon*/
			.setSmallIcon(R.drawable.ic_launcher)
			/*设置title*/
			.setContentTitle("通知")
			/*设置详细文本*/
			.setContentText("Hello world");
	manager.notify(100, notifyBuilder.build());
}

代码里的注释已经很详细了,simNotification绑定到了一个Button。这样,我们已经实现了最简单的notification

2.创建一个点击跳转到其它Activity的Notification。无法通过左右滑动删除

/**
 * 点击跳转到指定Activity
 *
 * @param view
 */
public void largePicture(View view) {
     /*实例化NotificationManager以获取系统服务*/
    manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

    //点击的意图ACTION是跳转到Intent
    Intent resultIntent = new Intent(this, MainActivity.class);
    resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
    notifyBuilder = new NotificationCompat.Builder(this)
            /*设置large icon*/
            .setLargeIcon(bitmap)
             /*设置small icon*/
            .setSmallIcon(R.drawable.ic_launcher)
            /*设置title*/
            .setContentTitle("通知")
            /*设置详细文本*/
            .setContentText("Hello world")
             /*设置发出通知的时间为发出通知时的系统时间*/
            .setWhen(System.currentTimeMillis())
             /*设置发出通知时在status bar进行提醒*/
            .setTicker("来自问月的祝福")
            /*setOngoing(boolean)设为true,notification将无法通过左右滑动的方式清除
            * 可用于添加常驻通知,必须调用cancle方法来清除
            */
            .setOngoing(true)
             /*设置点击后通知消失*/
            .setAutoCancel(true)
             /*设置通知数量的显示类似于QQ那种,用于同志的合并*/
            .setNumber(2)
             /*点击跳转到MainActivity*/
            .setContentIntent(pendingIntent);

    manager.notify(121, notifyBuilder.build());
}

代码里的注释都很详细,加上前面的介绍相信大家都能理解了。

3.创建一个显示bitmap的notification,类似于屏幕截图的显示效果


/**
 * 类似于系统截图的效果
 *
 * @param view
 */
public void comNotification(View view) {

	/*实例化NotificationManager以获取系统服务*/
	manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

	/*获取bitmap*/
	Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
	notifyBuilder = new NotificationCompat.Builder(this)
			 /*设置small icon*/
			.setSmallIcon(R.drawable.ic_launcher)
			/*设置title*/
			.setContentTitle("通知")
			/*设置详细文本*/
			.setContentText("Hello world")
			.setWhen(System.currentTimeMillis())
			.setOngoing(true)
			.setNumber(2);

	NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
	bigPictureStyle.bigPicture(bitmap);
	notifyBuilder.setStyle(bigPictureStyle);

	manager.notify(121, notifyBuilder.build());
}

这里唯一需要注意的是加载图片最好不要在UI线程进行(这里只是为了演示)。


4.创建一个类似于日历事件的notification,并与Service进行交互。


/**
 * 创建一个类似于日历事件的notification
 * @param view
 */
public void add_action(View view) {

	myIntent = new Intent(getApplicationContext(), MyIntentService.class);

	myIntent.putExtra(myConstants.EXTRA_MESSAGE, " 来自问月的祝福");
	myIntent.setAction(myConstants.ACTION_PING);
	myIntent.putExtra(myConstants.EXTRA_TIMER, 1000);
	startService(myIntent);

}
IntentService代码如下,之后在需要时可以在此扩展IntentService,这里注意一下IntentService类的构造器的重载,super里面是你的路径名。
package me.androiddemo.canglangwenyue.test;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

/**
 * Created by canglangwenyue on 14-12-9.
 */
public class MyIntentService extends IntentService {

private NotificationManager manager;
private String message;
private int mMills;
NotificationCompat.Builder builder;

public MyIntentService() {
	// The super call is required. The background thread that IntentService
	// starts is labeled with the string argument you pass.
	super("me.androiddemo.canglangwenyuet.test");
}

@Override
protected void onHandleIntent(Intent intent) {

	message = intent.getStringExtra(myConstants.EXTRA_MESSAGE);

	mMills = intent.getIntExtra(myConstants.EXTRA_TIMER, myConstants.DEFAULT_TIMER_DURATION);

	NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

	String action = intent.getAction();
	issueNotification(intent,message);

	if (action.equals(myConstants.ACTION_PING)) {
		issueNotification(intent,message);
	}else if (action.equals(myConstants.ACTION_SNOOZE)) {
		notificationManager.cancel(myConstants.NOTIFICATION_ID);
		issueNotification(intent,"");
	}else if (action.equals(myConstants.ACTION_DISMISS)) {
		notificationManager.cancel(myConstants.NOTIFICATION_ID);
	}


}

private void issueNotification(Intent intent, String msg) {
	manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
	Intent dissmissItent = new Intent(this,MyIntentService.class);
	dissmissItent.setAction(myConstants.ACTION_DISMISS);
	PendingIntent disIntent = PendingIntent.getService(this,0,dissmissItent,0);

	Intent snoozeIntent = new Intent(this,MyIntentService.class);
	snoozeIntent.setAction(myConstants.ACTION_SNOOZE);
	PendingIntent snoopIntent = PendingIntent.getService(this,0,snoozeIntent,0);

	builder = new NotificationCompat.Builder(this)
			.setSmallIcon(R.drawable.ic_launcher)
			.setContentTitle("Information")
			.setContentText("lalallalala")
			.setDefaults(Notification.DEFAULT_ALL)
			.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
			.addAction(R.drawable.ic_launcher, "Dismiss", disIntent)
			.addAction(R.drawable.ic_launcher,"snooze",snoopIntent);


	Intent resultIntent = new Intent(this,MainActivity2.class);
	resultIntent.putExtra(myConstants.EXTRA_MESSAGE,msg);
	resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);


	PendingIntent resultPendingIntent = PendingIntent.getActivity(this,0,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);

	builder.setContentIntent(resultPendingIntent);
	//		manager.notify(myConstants.NOTIFICATION_ID,builder.build());
	startTimer(mMills);



}

private void startTimer(int mMills) {
	try {

		Thread.sleep(mMills);

	}catch (Exception e) {
		Log.d(myConstants.DEBUG_TAG, "ERROR");
	}
	issueNotification(builder);
}

private void issueNotification(NotificationCompat.Builder builder) {
	manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

	manager.notify(myConstants.NOTIFICATION_ID,builder.build());
}
}
这里只是实现了一个简单的Timer。参考一下就好。

5.创建一个自定义的notification,只要通过RemoteViews来获取你的XML布局文件,并通过.setContent(remoteViews)就好,大家只需要对比不同之处。

/**
 * 自定义notification样式
 *
 * @param view
 */
public void Cus_Notification(View view) {

	Toast.makeText(MainActivity.this, "AHa", Toast.LENGTH_LONG).show();
	/*实例化NotificationManager以获取系统服务*/
	manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
	RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.customnotification);

	remoteViews.setImageViewResource(R.id.imageView, R.drawable.psb);
	remoteViews.setTextViewText(R.id.textView, "Your Haven");

	remoteViews.setTextViewText(R.id.textView2, "YUI");
	remoteViews.setTextViewText(R.id.textView3, "豆瓣-FNM -我的红心 MHZ");

	remoteViews.setViewVisibility(R.id.my_large_button, View.VISIBLE);
	notifyBuilder = new NotificationCompat.Builder(this)
			.setContent(remoteViews)
			.setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL))
			 /*设置small icon*/
			.setSmallIcon(R.drawable.ic_launcher)
			/*设置title*/
			.setContentTitle("通知")
			/*设置详细文本*/
			.setTicker("Your Haven")
			.setContentText("Hello world")
			.setWhen(System.currentTimeMillis())
			.setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级
			.setOngoing(true);

	Notification noty = notifyBuilder.build();
	noty.contentView = remoteViews;
	manager.notify(313, noty);

}

这里只是添加了一个ImageView和三个TextView,大家可以进一步扩充,例如添加ImageButton,并通过BroadcastReceiver来监听。


6.最后在写一个带进度条指示器的notification吧,到了这里大家应该理解什么叫求同存异了吧,哈哈。至于其它的notification,例如FullScreen下的notification或者LockScreen的notification等,都是换汤不换药,大家只要按需设置相应的属性就好,具体可以查询官方文档。

/**
 * 有进度条的notification
 * @param view
 */
public void Pro_Notification(View view) {

	manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
	notifyBuilder = new NotificationCompat.Builder(this);
	notifyBuilder.setContentTitle("Picture Download")
			.setContentText("Download in progress")
			.setOngoing(true)
			.setSmallIcon(R.drawable.ic_launcher);
// Start a lengthy operation in a background thread
	new Thread(
			new Runnable() {
				@Override
				public void run() {
					int incr;
					// Do the "lengthy" operation 20 times
					for (incr = 0; incr <= 100; incr += 5) {
						// Sets the progress indicator to a max value, the
						// current completion percentage, and "determinate"
						// state
						notifyBuilder.setProgress(100, incr, false);
						// Displays the progress bar for the first time.
						manager.notify(0, notifyBuilder.build());
						// Sleeps the thread, simulating an operation
						// that takes time
						try {
							// Sleep for 5 seconds
							Thread.sleep(5 * 1000);
						} catch (InterruptedException e) {
							Log.d("NOTIFICATION", "sleep failure");
						}
					}
					// When the loop is finished, updates the notification
					notifyBuilder.setContentText("Download complete")
							// Removes the progress bar
							.setProgress(0, 0, false);
					manager.notify(213, notifyBuilder.build());
				}
			}
// Starts the thread by calling the run() method in its Runnable
	).start();

}

大概解释一下,就是在一个异步线程里面每隔5秒使notification的process增加5,循环结束后,在重新添加一个notification来显示下载完成。至于进度还有其他方式设置,这里就不一一介绍了,实际使用时可以传入具体的下载进度。

好了,感觉已经写了好多了,最后来总结一下notification的使用吧。(一)通过以下几个步骤就可以获得一个notification的实现:

1.获取NotificationManager实例,即获得状态通知栏管理权;

 /*实例化NotificationManager以获取系统服务*/
    manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

2.实例化notification的constructor

notifyBuilder = new NotificationCompat.Builder(this)

3.对notifyBuilder设置各种属性

 /**
             * 前三个属性必须设置
             */
            /*设置small icon*/
            .setSmallIcon(R.drawable.ic_launcher)
            /*设置title*/
            .setContentTitle("通知")
            /*设置详细文本*/
            .setContentText("Hello world")
             /*设置发出通知的时间为发出通知时的系统时间*/
            .setWhen(System.currentTimeMillis())
             /*设置发出通知时在status bar进行提醒*/
            .setTicker("来自问月的祝福")
             /*设置点击后通知消失*/
            .setAutoCancel(true)
                    /**
                     * 设置
                     notification的默认效果有以下几种
                     Notification.DEFAULT_ALL:铃声、闪光、震动均系统默认。
                     Notification.DEFAULT_SOUND:系统默认铃声。
                     Notification.DEFAULT_VIBRATE:系统默认震动。
                     Notification.DEFAULT_LIGHTS:系统默认闪光。
                     */
            .setDefaults(Notification.DEFAULT_VIBRATE)
             /*setOngoing(boolean)设为true,notification将无法通过左右滑动的方式清除
            * 可用于添加常驻通知,必须调用cancle方法来清除
            */
            .setOngoing(true)
             /*设置通知数量的显示类似于QQ那种,用于同志的合并*/
            .setNumber(2);

4.显示notification

       manager.notify(100, notifyBuilder.build());

(二)一些常用的属性函数

.setDefaults(int defaults)用于向通知添加声音、闪灯和振动效果的最简单、使用默认(defaults)属性,具体在上述代码中有写到。

.setVibrate(long[] pattern)用于设置是否开启震动,true为开启

.setSound(Uri sound)用于设置通知铃声

.setPriority(int pri)用于设置优先级,同样之前有详细讲解

.setOngoing(boolean ongoing)设置为true则为常驻通知栏的通知类似于墨迹天气那种的效果。

setProgress(int max, int progress,boolean indeterminate)

用于设置进度的notification




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。