Notification使用詳解之二:可更新進度的通知
上次和大家分享了關於Notification的基礎應用,包括簡單的通知和自定義檢視的通知。今天和大家分享一下如何實現一個可更新進度的通知。
我們將會模擬一個下載任務,先啟動一個執行緒負責模擬下載工作,在這個過程中更新進度資訊,然後下載執行緒把最新的進度資訊以訊息的形式,傳送到UI執行緒的訊息佇列中,最後UI執行緒負責根據最新的進度資訊來更新進度通知的UI介面。
好,大概就是這個步驟。接下來我們根據具體的例項來演示一下這個過程。
我們新建一個notification專案,然後修改/res/layout/main.xml佈局檔案,程式碼如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <Button
- android:id="@+id/download"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="download"
- android:onClick="download"/>
- <Button
- android:id="@+id/cancel"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="cancel"
- android:onClick="cancel"/>
- </LinearLayout>
注意,為了使示例中的Java程式碼看起來結構更加清晰,我們將按鈕的點選事件都定義在佈局檔案中。
然後再來看一下MainActivity.java的程式碼:
- package com.scott.notification;
- import android.app.Activity;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.widget.RemoteViews;
- public class MainActivity extends Activity {
- private static final int NOTIFY_ID = 0;
- private boolean cancelled;
- private NotificationManager mNotificationManager;
- private Notification mNotification;
- private Context mContext = this;
- private Handler handler = new Handler() {
- public void handleMessage(android.os.Message msg) {
- switch (msg.what) {
- case 1:
- int rate = msg.arg1;
- if (rate < 100) {
- // 更新進度
- RemoteViews contentView = mNotification.contentView;
- contentView.setTextViewText(R.id.rate, rate + "%");
- contentView.setProgressBar(R.id.progress, 100, rate, false);
- } else {
- // 下載完畢後變換通知形式
- mNotification.flags = Notification.FLAG_AUTO_CANCEL;
- mNotification.contentView = null;
- Intent intent = new Intent(mContext, FileMgrActivity.class);
- PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
- mNotification.setLatestEventInfo(mContext, "下載完成", "檔案已下載完畢", contentIntent);
- }
- // 最後別忘了通知一下,否則不會更新
- mNotificationManager.notify(NOTIFY_ID, mNotification);
- break;
- case 0:
- // 取消通知
- mNotificationManager.cancel(NOTIFY_ID);
- break;
- }
- };
- };
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- public void download(View view) {
- mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- int icon = R.drawable.down;
- CharSequence tickerText = "開始下載";
- long when = System.currentTimeMillis();
- mNotification = new Notification(icon, tickerText, when);
- // 放置在"正在執行"欄目中
- mNotification.flags = Notification.FLAG_ONGOING_EVENT;
- RemoteViews contentView = new RemoteViews(mContext.getPackageName(), R.layout.download_notification_layout);
- contentView.setTextViewText(R.id.fileName, "AngryBird.apk");
- // 指定個性化檢視
- mNotification.contentView = contentView;
- // intent為null,表示點選通知時不跳轉
- PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, null, 0);
- // 指定內容意圖
- mNotification.contentIntent = contentIntent;
- mNotificationManager.notify(NOTIFY_ID, mNotification);
- new Thread() {
- public void run() {
- startDownload();
- };
- }.start();
- }
- public void cancel(View view) {
- cancelled = true;
- }
- private void startDownload() {
- cancelled = false;
- int rate = 0;
- while (!cancelled && rate < 100) {
- try {
- // 模擬下載進度
- Thread.sleep(500);
- rate = rate + 5;
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- Message msg = handler.obtainMessage();
- msg.what = 1;
- msg.arg1 = rate;
- handler.sendMessage(msg);
- }
- if (cancelled) {
- Message msg = handler.obtainMessage();
- msg.what = 0;
- handler.sendMessage(msg);
- }
- }
- }
值得注意的是,在控制下載執行緒時使用了cancelled這個boolean值標誌變數,對於執行緒的控制更好一些,不建議使用Thread.interrupt()去中斷一個執行緒。另外,對於更新通知的UI介面時,要記住呼叫NotificationManager.notify(int id, Notification notification)方法通知一下,否則即使設定了新值,也不會起作用的。
程式中用到的帶進度的通知佈局/res/layout/download_notification_layout.xml佈局檔案程式碼如下:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:padding="3dp">
- <ImageView
- android:id="@+id/imageView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="3dp"
- android:src="@drawable/down"/>
- <TextView
- android:id="@+id/fileName"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_toRightOf="@id/imageView"
- android:layout_alignBottom="@id/imageView"
- android:gravity="center_vertical"
- android:textColor="#000"/>
- <TextView
- android:id="@+id/rate"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/imageView"
- android:layout_alignRight="@id/imageView"
- android:gravity="center"
- android:text="0%"
- android:textColor="#000"/>
- <ProgressBar
- android:id="@+id/progress"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/fileName"
- android:layout_alignLeft="@id/fileName"
- android:max="100"
- android:progress="0"/>
- </RelativeLayout>
該通知的佈局使用了相對佈局,更加靈活易用,所以推薦大家多使用相對佈局。
對於MainActivity.java中涉及到的FileMgrActivity,它是一個簡單的介面,這裡就不在介紹了,that's not the point。
最後我們跑一下程式,看看效果如何:
貌似還不錯,好了,今天先到這裡,下次再找機會分享
相關文章
- Notification使用詳解之三:通過服務更新進度通知&在Activity中監聽服務進度
- Android Notification 通知詳解Android
- [轉]Android 通知Notification 詳解Android
- 【Android】狀態列通知Notification、NotificationManager詳解Android
- Notification使用詳解之四:由後臺服務向Activity傳送進度資訊
- 【Android】狀態列通知Notification、NotificationManager詳解(轉載)Android
- oreo上的notification詳解
- Flutter 通知(Notification)冒泡原理Flutter
- Notification桌面通知實踐
- Android 通知之 NotificationAndroid
- android之Notification通知Android
- Android Notification 詳解Android
- Android多種進度條使用詳解Android
- Android通知Notification全面剖析Android
- HTML5 桌面通知:Notification APIHTMLAPI
- Android 8 通知渠道(Notification Channels)Android
- Android通知之進度條對話方塊通知Android
- 聊聊HTML5中的Web Notification桌面通知HTMLWeb
- Android Notification通知欄的必備姿勢Android
- Flutter學習筆記(35)--通知NotificationFlutter筆記
- Android呼叫訊息欄通知(Notification)Android
- 訊息通知(Notification)/使用者觸達系統設計
- jQuery實進度條效果詳解jQuery
- Notification API,為你的網頁新增桌面通知推送API網頁
- H5 notification瀏覽器桌面通知H5瀏覽器
- 瀏覽器語音桌面通知,Notification API瀏覽器API
- 訊息通知(Notification)系統最佳化
- Android 特殊使用者通知用法彙總 - Notification 原始碼分析Android原始碼
- JavaScript 動態進度條效果詳解JavaScript
- git使用之二——.gitignore檔案詳解Git
- Spring AOP中的前置通知和後置通知詳解Spring
- Objective-C中的老闆是這樣發通知的(Notification)Object
- js實現動態進度條詳解JS
- 程式設計技巧│瀏覽器 Notification 桌面推送通知程式設計瀏覽器
- android之Notification監聽系統清除通知欄Android
- Threejs之二:相機詳解JS
- Git詳解之二:Git基礎Git
- User Notification Framework 框架的使用Framework框架