1. 程式人生 > >Notification仿QQ訊息通知欄效果點選清除訊息

Notification仿QQ訊息通知欄效果點選清除訊息

1.先看效果圖(哈哈網上沒到的錄取動態圖都太繁瑣不方便,無非就是用第三方外掛錄製,或者Android自身帶的adb命令錄製,Androidstudio自身帶的錄製工具,這裡博主用的是PC版的應用寶直接就能錄製動態圖比其他方式更快更直接,不是在給應用寶打廣告是真的很方便,不信的可以自己試試,最後博主會把步驟放在最後)


2.Notification的介紹

2.1因為一些Android版本的相容性問題,對於Notification而言,Android3.0是一個分水嶺,在其之前構建Notification推薦使用Notification.Builder構建,而在Android3.0之後,一般推薦使用NotificationCompat.Builder構建。

NotificationManager nm;
		nm = (NotificationManager)getSystemService(Activity.NOTIFICATION_SERVICE);
		int drawable = R.drawable.ic_launcher;
		Notification notification = new Notification(drawable, "門鎖狀態發生改變",
				System.currentTimeMillis());
		Intent intent2 = new Intent(MainActivity.this, FirstActivity.class);
		PendingIntent myIntent = PendingIntent.getActivity(this, 0, intent2, 0);
		notification.setLatestEventInfo(this, "門鎖狀態發生變化", "關鎖", myIntent);
		notification.defaults |= Notification.DEFAULT_SOUND;// 預設聲音
		notification.defaults |= Notification.DEFAULT_VIBRATE;// 震動
		nm.notify(0, notification);
以上是3.0之前的Notification的基本使用就不多介紹了,因為樓主下面的開發都是在3.0之後使用的是NotificationCompat.Builder

2.2 

  Notification —— 通知,是一種讓你的應用程式在不使用Activity的情況下警示使用者。它是看不見的程式元件(Broadcast Receiver,Service和不活躍的Activity)警示使用者有需要注意的事件發生的最好途徑。 Notification 是由NotificationManager(系統服務)統一管理的。

         一般來說, 一個Notification應該傳送的訊息包括:

                 1 、一個狀態條圖示      

                 2、在拉伸的狀態列視窗中顯示額外的資訊和啟動一個Application的Intent 

                 3、閃燈或LED

                 4、電話震動 

         在狀態列(Status Bar)中,通知主要有兩類(使用FLAG_標記,後面講解到):

                 1、正在執行的事件

                 2、通知事件 

     Notification圖解如下:


 Notification類介紹:

         常量

              //表示傳送一個Notification的所攜帶的效果

             DEFAULT_ALL              使用預設欄位

             DEFAULT_LIGHTS       預設閃光   後來得知需要新增閃光燈許可權VIBRATE: Android.permission.FLASHLIGHT

             DEFAULT_SOUND      預設聲音(uri,指向路徑)

             DEFAULT_VIRATE       預設震動,後來得知需要新增震動許可權VIBRATE: Android.permission.VIBRATE

          PS:以上的效果常量可以累加,即通過setDefaults屬性   (有些效果只能在真機上才有,比如震動)

            //設定Flag位

         FLAG_AUTO_CANCEL           該通知能被狀態列的清除按鈕給清除掉

           FLAG_NO_CLEAR                  該通知不能被狀態列的清除按鈕給清除掉

            FLAG_ONGOING_EVENT      通知放置在正在執行

    常用欄位  

contentView                  通知在狀態列的顯示View(自定義,具體請看下文) ,常與contentIntent配合使用,點選該通知後,

                                          即觸發contentIntent

           contentIntent                 設定PendingIntent物件,點選該通知時傳送該Intent

           flags                                  設定flag位,例如FLAG_NO_CLEAR等

           defaults                             新增效果

           tickerText                        顯示在狀態列中的文字

           when                               傳送此通知的時間戳

           icon                                  設定圖示

    常用方法介紹

功能: 顯示在拉伸狀態列中的Notification屬性,點選後將傳送PendingIntent物件。

        引數:   context             上下文環境

                      contentTitle      狀態列中的大標題

                      contentText      狀態列中的小標題

                      contentIntent    點選後將傳送PendingIntent物件

        另外的就是Notification的幾步不同構造方法了,其構造方法的引數含義如上,請參考SDK 。

PendingIntent第四個屬性介紹:

FLAG_CANCEL_CURRENT:如果構建的PendingIntent已經存在,則取消前一個,重新構建一個。

FLAG_NO_CREATE:如果前一個PendingIntent已經不存在了,將不再構建它。
FLAG_ONE_SHOT:表明這裡構建的PendingIntent只能使用一次。
FLAG_UPDATE_CURRENT:如果構建的PendingIntent已經存在,則替換它,常用。

程式碼中樓主沒有用PendingIntent攜帶Intent傳值原因:

PendingIntent包含了Intent及Context,所以就算Intent所屬程式結束,PendingIntent依然有效,可以在其他程式中使用。

樓主反覆測試發現intent傳過來的值始終有效,也就是說沒有新的值傳進來,該值一直是上一個值,因為樓主要的效果是

只需要使用一次該值,使用完就初始化,但是結果樓主發現怎麼初始化都是原來的值所以樓主猜測該值很有可能一直存在

記憶體中,當樓主殺死APP時重新進來值得初始化的所以,讀者在使用時最好考慮傳過來的值是否有多餘使用之處或者該值

覺得你APP下一步走向,需要根據傳過來的值做判斷,最好用一個全域性變數傳值,樓主使用的是繼承自Application設定的

  全域性變數值

NotificationManager類

 通過獲取系統服務來獲取該物件:

 NotificationManager mNotificationManager = (NotificationManager)getSystemServic(Context.NOTIFICATION_SERVICE) ;

常用方法:

        public  void cancelAll()                  移除所有通知         (只是針對當前Context下的Notification)

        public  void cancel(int id)              移除標記為id的通知 (只是針對當前Context下的所有Notification)

        public  voidnotify(String tag ,int id, Notification notification)              將通知加入狀態列, 標籤為tag,標記為id

        public  void notify(int id, Notification notification)                                 將通知加入狀態列,,標記為id

   必須新增的屬性:

  小圖示,使用setSamllIcon()方法設定。
  通知提示訊息,使用setTicker方法設定。

 可設定屬性:

  通知欄點選是否可以清除setAutoCancel

  設定PendingIntent意圖setContentIntent

  設定自定義佈局setContent(博主使用的是RemoteViews自定義更強大的佈局)

  其他的屬性有待讀者自行在程式碼使用體會

程式碼實現:廣播類實現

package com.example.notifications;

import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.RemoteViews;

public class MyBroadcastReceiver extends BroadcastReceiver {

	private MyApplication application;
	private Context context1;

	@Override
	public void onReceive(Context context, Intent intent) {
		this.context1 = context;
		if (intent.getStringExtra("info").equals("廣播發送了")) {
			Log.i("靜態廣播:", "廣播我已經接受了");
		}

		Message message = handler.obtainMessage();
		message.what = 0x11;
		handler.sendMessage(message);

	}

	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 0x11:
				application = (MyApplication) context1.getApplicationContext();
				int first = application.getInfo_number();
				Log.i("yuanlai", "---" + first);
				first++;
				Date nowTime = new Date(System.currentTimeMillis());
				SimpleDateFormat sdFormatter = new SimpleDateFormat("HH:mm");
				String retStrFormatNowDate = sdFormatter.format(nowTime);
				application.setInfo_number(first);
				Log.i("houlai", "---" + application.getInfo_number());
				RemoteViews contentViews = new RemoteViews(context1.getPackageName(), R.layout.layout_item);
				// 通過控制元件的Id設定屬性
				contentViews.setImageViewResource(R.id.imageView1, R.drawable.icon);
				contentViews.setTextViewText(R.id.textView1, "門狀態發生變化");
				contentViews.setTextViewText(R.id.textView2, "開鎖");
				contentViews.setTextViewText(R.id.textView3, " (" + first + "條新訊息)");
				contentViews.setTextViewText(R.id.textView4, "" + retStrFormatNowDate);
				// 點選通知欄跳轉的activity
				Intent intent = new Intent(context1, FirstActivity.class);
				PendingIntent pendingIntent = PendingIntent.getActivity(context1, 0, intent,
						PendingIntent.FLAG_CANCEL_CURRENT);

				NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context1)
						.setSmallIcon(R.drawable.icon).setTicker("new message");
				// 自動管理通知欄訊息
				mBuilder.setAutoCancel(true);
				mBuilder.setContentIntent(pendingIntent);
				/// 自定義佈局
				mBuilder.setContent(contentViews);
				// 使用預設提示音
				mBuilder.setDefaults(Notification.DEFAULT_ALL);
				NotificationManager mNotificationManager = (NotificationManager) context1
						.getSystemService(context1.NOTIFICATION_SERVICE);
				mNotificationManager.notify(1, mBuilder.build());

				break;

			default:
				break;
			}
		}

	};

}

模擬傳送通知欄程式碼實現:

package com.example.notifications;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

/*
 * 通知欄應用
 */
public class MainActivity extends Activity implements OnClickListener {
	private Button btn_show;
	private TextView tv_show;
	private int btn_number = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		initView();
	}

	private void initView() {
		btn_show = (Button) findViewById(R.id.btn_show);
		tv_show = (TextView) findViewById(R.id.tv_show);

		btn_show.setOnClickListener(this);
	}

	private void showNotify() {
		Intent intent = new Intent();
		intent.setAction("MLY");
		intent.putExtra("info", "廣播發送了");
		sendBroadcast(intent);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_show:
			showNotify();
			btn_number++;
			tv_show.setText("傳送了" + btn_number + "次廣播");
			break;
		default:
			break;
		}
	}

	@Override
	protected void onStop() {
		btn_number = 0;
		tv_show.setText("傳送了" + btn_number + "次廣播");
		super.onStop();
	}

	@Override
	protected void onPause() {
		btn_number = 0;
		tv_show.setText("傳送了" + btn_number + "次廣播");
		super.onPause();
	}

	@Override
	protected void onDestroy() {
		btn_number = 0;
		super.onDestroy();
	}
}

清除訊息通知實現:

package com.example.notifications;

import android.os.Bundle;
import android.widget.TextView;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;

public class FirstActivity extends Activity {
	NotificationManager notificationManager;
	MyApplication app;
	TextView tv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_first);
		app=(MyApplication) getApplication();
		tv=(TextView) findViewById(R.id.firstActivity_tv);
		notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		notificationManager.cancel(1);
        app.setInfo_number(0);
        tv.setText("訊息已清空");
	}

}

4.應用寶生成gif介紹:

4.1下載PC版應用寶連結安卓手機開啟應用寶介面



點選預覽儲存直接進去有儲存,儲存成gif就行

5. 如有不對的地方歡迎指正,博主後續會繼續修改該文章