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键,在其上方会出现粗略的方法参数的说明,点击如图上方的注射器,便能完整的查看方法的说明,如下图所示:


官方给出的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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容