Notification使用详解之二:可更新进度的通知

Stella981
• 阅读 694

上次和大家分享了关于Notification的基础应用,包括简单的通知和自定义视图的通知。今天和大家分享一下如何实现一个可更新进度的通知。

我们将会模拟一个下载任务,先启动一个线程负责模拟下载工作,在这个过程中更新进度信息,然后下载线程把最新的进度信息以消息的形式,发送到UI线程的消息队列中,最后UI线程负责根据最新的进度信息来更新进度通知的UI界面。

好,大概就是这个步骤。接下来我们根据具体的实例来演示一下这个过程。

我们新建一个notification项目,然后修改/res/layout/main.xml布局文件,代码如下:

[html] view plain copy

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:orientation="vertical"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <Button
  6. android:id="@+id/download"
  7. android:layout_width="fill_parent"
  8. android:layout_height="wrap_content"
  9. android:text="download"
  10. android:onClick="download"/>
  11. <Button
  12. android:id="@+id/cancel"
  13. android:layout_width="fill_parent"
  14. android:layout_height="wrap_content"
  15. android:text="cancel"
  16. android:onClick="cancel"/>
  17. </LinearLayout>

注意,为了使示例中的Java代码看起来结构更加清晰,我们将按钮的点击事件都定义在布局文件中。

然后再来看一下MainActivity.java的代码:

[java] view plain copy

  1. package com.scott.notification;

  2. import android.app.Activity;

  3. import android.app.Notification;

  4. import android.app.NotificationManager;

  5. import android.app.PendingIntent;

  6. import android.content.Context;

  7. import android.content.Intent;

  8. import android.os.Bundle;

  9. import android.os.Handler;

  10. import android.os.Message;

  11. import android.view.View;

  12. import android.widget.RemoteViews;

  13. public class MainActivity extends Activity {

  14. private static final int NOTIFY_ID = 0;

  15. private boolean cancelled;

  16. private NotificationManager mNotificationManager;

  17. private Notification mNotification;

  18. private Context mContext = this;

  19. private Handler handler = new Handler() {

  20. public void handleMessage(android.os.Message msg) {

  21. switch (msg.what) {

  22. case 1:

  23. int rate = msg.arg1;

  24. if (rate < 100) {

  25. // 更新进度

  26. RemoteViews contentView = mNotification.contentView;

  27. contentView.setTextViewText(R.id.rate, rate + "%");

  28. contentView.setProgressBar(R.id.progress, 100, rate, false);

  29. } else {

  30. // 下载完毕后变换通知形式

  31. mNotification.flags = Notification.FLAG_AUTO_CANCEL;

  32. mNotification.contentView = null;

  33. Intent intent = new Intent(mContext, FileMgrActivity.class);

  34. PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);

  35. mNotification.setLatestEventInfo(mContext, "下载完成", "文件已下载完毕", contentIntent);

  36. }

  37. // 最后别忘了通知一下,否则不会更新

  38. mNotificationManager.notify(NOTIFY_ID, mNotification);

  39. break;

  40. case 0:

  41. // 取消通知

  42. mNotificationManager.cancel(NOTIFY_ID);

  43. break;

  44. }

  45. };

  46. };

  47. @Override

  48. public void onCreate(Bundle savedInstanceState) {

  49. super.onCreate(savedInstanceState);

  50. setContentView(R.layout.main);

  51. }

  52. public void download(View view) {

  53. mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

  54. int icon = R.drawable.down;

  55. CharSequence tickerText = "开始下载";

  56. long when = System.currentTimeMillis();

  57. mNotification = new Notification(icon, tickerText, when);

  58. // 放置在"正在运行"栏目中

  59. mNotification.flags = Notification.FLAG_ONGOING_EVENT;

  60. RemoteViews contentView = new RemoteViews(mContext.getPackageName(), R.layout.download_notification_layout);

  61. contentView.setTextViewText(R.id.fileName, "AngryBird.apk");

  62. // 指定个性化视图

  63. mNotification.contentView = contentView;

  64. // intent为null,表示点击通知时不跳转

  65. PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, null, 0);

  66. // 指定内容意图

  67. mNotification.contentIntent = contentIntent;

  68. mNotificationManager.notify(NOTIFY_ID, mNotification);

  69. new Thread() {

  70. public void run() {

  71. startDownload();

  72. };

  73. }.start();

  74. }

  75. public void cancel(View view) {

  76. cancelled = true;

  77. }

  78. private void startDownload() {

  79. cancelled = false;

  80. int rate = 0;

  81. while (!cancelled && rate < 100) {

  82. try {

  83. // 模拟下载进度

  84. Thread.sleep(500);

  85. rate = rate + 5;

  86. } catch (InterruptedException e) {

  87. e.printStackTrace();

  88. }

  89. Message msg = handler.obtainMessage();

  90. msg.what = 1;

  91. msg.arg1 = rate;

  92. handler.sendMessage(msg);

  93. }

  94. if (cancelled) {

  95. Message msg = handler.obtainMessage();

  96. msg.what = 0;

  97. handler.sendMessage(msg);

  98. }

  99. }

  100. }

值 得注意的是,在控制下载线程时使用了cancelled这个boolean值标志变量,对于线程的控制更好一些,不建议使用 Thread.interrupt()去中断一个线程。另外,对于更新通知的UI界面时,要记住调用 NotificationManager.notify(int id, Notification notification)方法通知一下,否则即使设置了新值,也不会起作用的。

程序中用到的带进度的通知布局/res/layout/download_notification_layout.xml布局文件代码如下:

[html] view plain copy

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="fill_parent"
  3. android:layout_height="fill_parent"
  4. android:padding="3dp">
  5. <ImageView
  6. android:id="@+id/imageView"
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content"
  9. android:layout_margin="3dp"
  10. android:src="@drawable/down"/>
  11. <TextView
  12. android:id="@+id/fileName"
  13. android:layout_width="fill_parent"
  14. android:layout_height="fill_parent"
  15. android:layout_toRightOf="@id/imageView"
  16. android:layout_alignBottom="@id/imageView"
  17. android:gravity="center_vertical"
  18. android:textColor="#000"/>
  19. <TextView
  20. android:id="@+id/rate"
  21. android:layout_width="fill_parent"
  22. android:layout_height="wrap_content"
  23. android:layout_below="@id/imageView"
  24. android:layout_alignRight="@id/imageView"
  25. android:gravity="center"
  26. android:text="0%"
  27. android:textColor="#000"/>
  28. <ProgressBar
  29. android:id="@+id/progress"
  30. style="?android:attr/progressBarStyleHorizontal"
  31. android:layout_width="fill_parent"
  32. android:layout_height="wrap_content"
  33. android:layout_below="@id/fileName"
  34. android:layout_alignLeft="@id/fileName"
  35. android:max="100"
  36. android:progress="0"/>
  37. </RelativeLayout>

该通知的布局使用了相对布局,更加灵活易用,所以推荐大家多使用相对布局。

对于MainActivity.java中涉及到的FileMgrActivity,它是一个简单的界面,这里就不在介绍了,that's not the point。

最后我们跑一下程序,看看效果如何:

Notification使用详解之二:可更新进度的通知 Notification使用详解之二:可更新进度的通知

貌似还不错,好了,今天先到这里,下次再找机会分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章教会你使用JS+CSS实现一个简单加载进度条的效果
大家好,我是前端进阶者,今天给大家来做个小项目,一起来看看吧一、前言我们经常在网页上,游戏界面加载时会看到加载进度条的效果,我们往往会以为这些加载进度条的效果,很难实现。今天教大家JSCSS结合做简单一个加载进度条的效果。二、项目准备软件:HBuilderX。三、项目实现1\.body创建2个div,外部div添加id"progress"属
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Notification使用详解之一:基础应用
在消息通知时,我们经常用到两个组件Toast和Notification。特别是重要的和需要长时间显示的信息,用Notification就最合适不过了。当有消息通知时,状态栏会显示通知的图标和文字,通过下拉状态栏,就可以看到通知信息了,Android这一创新性的UI组件赢得了用户的一致好评,就连苹果也开始模仿了。今天我们就结合实例,探讨一下Notifica
Wesley13 Wesley13
2年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Stella981 Stella981
2年前
Android10.0通知Notification的使用这一篇就够了
文章目录前言通知概述不同android版本上通知功能通知的结构创建通知1.创建渠道2.设置点击事件3.构造Notification对象并显示通知通知的操作1.添加操作按钮2.添加进度条3.设置锁定屏幕公开范围4.更
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Stella981 Stella981
2年前
Notification使用详解之三:通过服务更新进度通知&在Activity中监听服务进度
上次我们讲到如何实现一个可更新的进度通知,实现的方式是启动一个线程模拟一个下载任务,然后根据任务进度向UI线程消息队列发送进度消息,UI线程根据进度消息更新通知的UI界面。可是在实际应用中,我们一般会将上传、下载等比较耗时的后台任务以服务的形式运行,更新进度通知也是交由后台服务来完成的。不过有的时候,除了在通知里面显示进度信息,我们也要在Activit
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这