您的位置:首页 > 其它

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

2012-10-29 16:53 483 查看
本文来自于:/article/7553418.html

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

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

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

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

[html] view
plaincopy

<?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的代码:

[java] view
plaincopy

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布局文件代码如下:

[html] view
plaincopy

<?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。

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





貌似还不错,好了,今天先到这里,下次再找机会分享。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐