Android自定義通知

引言
在日常的生活中中,我們的手機每天會收到各種各樣的通知,比如短信通知,QQ消息通知,微信消息通知,軟件更新通知等,不同的通知,樣式也不相同。那么我們在開發(fā)過程中如何去研究這些通知并運用到自己的項目中去呢?
一 首先,對于通知,Android給我們提供一般的通知和自定義的通知,一般的通知通常比較簡單,這里主要介紹一下自定義通知。必須要知道和通知有關的兩個類:Notification 和NotificationManager
Notification為通知信息類,它里面對應了通知欄的各個屬性
NotificationManager : 是狀態(tài)欄通知的管理類,負責發(fā)通知、清除通知等操作。
注意: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的區(qū)別,我們都知道Intent作為一個意圖,通常作為跳轉的一種形式的聲明,Intent一般是用作Activity、Sercvice、BroadcastReceiver之間傳遞數據,又或者體現的是及時啟動,是現在進行時的一種狀態(tài)體現。而PendingIntent則更多的是體現出的是即將要發(fā)生的事情,是將來時。PendingIntent更多的適用的場景大多數用于Notifycation,得到PendingIntent的一個實例通常是通過getactivity(往activity中去跳轉),又或者是getBroadcast(去發(fā)送一個特定的廣播用于完成指定的事情)等。至于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僅能執(zhí)行一次,執(zhí)行完后自動取消
② FLAG_NO_CREATE表示如果描述的PendingIntent不存在,并不創(chuàng)建相應的PendingIntent,而是返回NULL
③ FLAG_CANCEL_CURRENT表示相應的PendingIntent已經存在,則取消前者,然后創(chuàng)建新的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;            
}        
}    
}
}
}

對于自定義通知的講解,還有很多需要注意的細節(jié),在這里就不一 一進行闡述了,現提供幾篇文章,都寫的非常好,有興趣的同學可以研究一下:

http://www.lxweimin.com/p/426d85f34561
http://blog.csdn.net/guolin_blog/article/details/50945228
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容