引言
在日常的生活中中,我們的手機每天會收到各種各樣的通知,比如短信通知,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