Android自定义通知

引言
在日常的生活中中,我们的手机每天会收到各种各样的通知,比如短信通知,QQ消息通知,微信消息通知,软件更新通知等,不同的通知,样式也不相同。那么我们在开发过程中如何去研究这些通知并运用到自己的项目中去呢?
一 首先,对于通知,Android给我们提供一般的通知和自定义的通知,一般的通知通常比较简单,这里主要介绍一下自定义通知。必须要知道和通知有关的两个类:Notification 和NotificationManager
Notification为通知信息类,它里面对应了通知栏的各个属性
NotificationManager : 是状态栏通知的管理类,负责发通知、清除通知等操作。
注意:NotificationManager 是一个系统Service,所以必须通过getSystemService(NOTIFICATION_SERVICE)方法来获取。
二 那么自定义一个通知的具体思路是什么样的呢?
①首先要通过RemoteViews来加载自定义的布局文件,然后给自定义的布局文件赋值

Notification的自定义布局是RemoteViews,和其他RemoteViews一样,在自定义视图布局文件中,仅支持FrameLayout、LinearLayout、RelativeLayout三种布局控件和AnalogClock、Chronometer、Button、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView和AdapterViewFlipper这些显示控件,不支持这些类的子类或Android提供的其他控件。否则会引起ClassNotFoundException异常,所以说即使是自定义的textview也是不可以的

②其次要获得自定义通知的管理类,获取方式如下:

NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder =newNotificationCompat.Builder(this);//NotificationCompat是v7包下的类,来处理新老版本的兼容问题
builder.setContent(notify_view)
.setTicker("有新的软件更新")
.setPriority(Notification.PRIORITY_DEFAULT)
.setSmallIcon(R.mipmap.ic_launcher);//这个属性是自定义通知里面必须要传递的,否则通知不显示
Notification notification=builder.build();
Intent notificationIntent =newIntent(this, SecondActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,0, notificationIntent,0);//PendingIntent获取的是活动
notification.contentIntent= contentIntent;//把跳转意图赋值给通知
notification.flags=Notification.FLAG_AUTO_CANCEL;//这句代码的意思是当点击通知跳转到新的activity后,该通知消失
manager.notify(1, notification);
备注:当然该自定义布局中没有button,立即更新和稍后更新我是用textview来代替的,只是为了模拟一下点击效果,具体的点击事件的操作稍后在描述,l另外,如果考虑到2.3以下通知栏的适配,我们还应该在凡是2.3以下的系统,把立即更新和稍后更新两个按钮给隐藏掉

通过上述代码需要注意以下几点:
1 上述代码中PengingIntent与我们平时频繁使用Intent的区别,我们都知道Intent作为一个意图,通常作为跳转的一种形式的声明,Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,又或者体现的是及时启动,是现在进行时的一种状态体现。而PendingIntent则更多的是体现出的是即将要发生的事情,是将来时。PendingIntent更多的适用的场景大多数用于Notifycation,得到PendingIntent的一个实例通常是通过getactivity(往activity中去跳转),又或者是getBroadcast(去发送一个特定的广播用于完成指定的事情)等。至于getBroadcast里面的参数,我们怎么来查看文档呢?以studio为例,鼠标放在getBroadcast处,点击ctrl键,在其上方会出现粗略的方法参数的说明,点击如图上方的注射器,便能完整的查看方法的说明,如下图所示:


Android自定义通知_第1张图片

官方给出的getBroadcast的参数说明如下:

public staticPendingIntent getBroadcast (Context context,intrequestCode, Intent intent,intflags)
Added in API level1
Retrieve a PendingIntent that will perform a broadcast, like calling Context.sendBroadcast().
For security reasons, the Intent you supply here should almost always be an explicit intent, that is specify an explicit component to be delivered to through Intent.setClass
Parameters
context
The Context in whichthisPendingIntent should perform the broadcast.
requestCode
Private request codeforthe sender
intent
The Intent to be broadcast.
flags
May be FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens.
Returns
Returns an existing ornewPendingIntent matching the given parameters. Mayreturn nullonlyifFLAG_NO_CREATE has been supplied.

2 PendingIntent的位标识符:
① FLAG_ONE_SHOT 表示返回的PendingIntent仅能执行一次,执行完后自动取消
② FLAG_NO_CREATE表示如果描述的PendingIntent不存在,并不创建相应的PendingIntent,而是返回NULL
③ FLAG_CANCEL_CURRENT表示相应的PendingIntent已经存在,则取消前者,然后创建新的PendingIntent,这个有利于数据保持为最新的,可以用于即时通信的通信场景
④ FLAG_UPDATE_CURRENT 表示更新的PendingIntent
整个activity的代码如下:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.app.Activity;import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.NotificationCompat;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener 
{    public final static String ACTION_UPDATE = "com.notifications.intent.action.Update";    
public UpdateBroadcastReceiver bReceiver;    
@Override    
protected void onCreate(Bundle savedInstanceState) {        
super.onCreate(savedInstanceState);        
setContentView(R.layout.activity_main);        
findViewById(R.id.btn_tip_notify_one).setOnClickListener(this);        findViewById(R.id.btn_tip_notify_two).setOnClickListener(this);        
initUpdateReceiver();   
}
/** 带按钮的通知栏点击广播接收 */
public void initUpdateReceiver()
{    bReceiver = new UpdateBroadcastReceiver();    
     IntentFilter intentFilter = new IntentFilter();    
    intentFilter.addAction(ACTION_UPDATE);    
    registerReceiver(bReceiver, intentFilter);
}
 
@Override
public void onClick(View v) {    
switch (v.getId()){        
case R.id.btn_tip_notify_one:            
RemoteViews notify_view=new RemoteViews(getPackageName(),R.layout.notify_one);            notify_view.setImageViewResource(R.id.iv_icon,R.mipmap.ic_launcher);            
notify_view.setTextViewText(R.id.tv_title,"有更新啦");            
notify_view.setTextViewText(R.id.tv_description,"修复一些重大bug,利于用户更好的使用app");            /
/点击的事件处理            
Intent buttonIntent = new Intent(ACTION_UPDATE);           
//立即更新按钮的相关信息的设置            
buttonIntent.putExtra("tag", 2);            
PendingIntent intent_paly = PendingIntent.getBroadcast(this, 2, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);            notify_view.setOnClickPendingIntent(R.id.update_now, intent_paly);            
//稍后更新按钮的相关信息的设置            
buttonIntent.putExtra("tag", 3);            
PendingIntent intent_next = PendingIntent.getBroadcast(this, 3, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);            notify_view.setOnClickPendingIntent(R.id.update_later, intent_next);            
NotificationManager manager=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);//NotificationCompat是v7包下的类,来处理新老版本的兼容问题            
builder.setContent(notify_view)                    
.setTicker("有新的软件更新")                    
.setPriority(Notification.PRIORITY_DEFAULT)                    
.setSmallIcon(R.mipmap.ic_launcher);//这个属性是自定义通知里面必须要传递的,否则通知不显示            
Notification notification=builder.build();            
Intent notificationIntent = new Intent(this, SecondActivity.class);            
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);//PendingIntent获取的是活动            notification.contentIntent = contentIntent;//把跳转意图赋值给通知            notification.flags=Notification.FLAG_AUTO_CANCEL;//这句代码的意思是当点击通知跳转到新的activity后,该通知消失            manager.notify(1, notification);            
break;        
case R.id.btn_tip_notify_two:            
break;    
}
}
public class UpdateBroadcastReceiver extends BroadcastReceiver {    
@Override   
 public void onReceive(Context context, Intent intent) {        
String action = intent.getAction();        
if(action.equals(ACTION_UPDATE)){           
 int buttonId = intent.getIntExtra("tag", 0);            
switch (buttonId) {                
case 2:                    
Toast.makeText(getApplicationContext(), "立即更新", Toast.LENGTH_SHORT).show();                   
 break;                
case 3:                    
Toast.makeText(getApplicationContext(), "稍后更新", Toast.LENGTH_SHORT).show();                    
break;                
default:                    
break;            
}        
}    
}
}
}

对于自定义通知的讲解,还有很多需要注意的细节,在这里就不一 一进行阐述了,现提供几篇文章,都写的非常好,有兴趣的同学可以研究一下:

http://www.jianshu.com/p/426d85f34561
http://blog.csdn.net/guolin_blog/article/details/50945228

你可能感兴趣的:(Android自定义通知)