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