項(xiàng)目中需要用到通知欄進(jìn)度條,查找了好多資料、鏈接如下:
- Android 為Notification加上一個(gè)進(jìn)度條
- Android實(shí)現(xiàn)Service后臺(tái)下載Notification進(jìn)度條
- Notification使用詳解之三:通過(guò)服務(wù)更新進(jìn)度通知&在Activity中監(jiān)聽(tīng)服務(wù)進(jìn)度
- android service startService bindService
- Android中BindService方式使用的理解
- [Android 機(jī)制] 大家?guī)兔匆幌逻@個(gè)BUG.
- Android 的service的定義可以 作為內(nèi)部類使用嗎?
我先簡(jiǎn)后難寫了兩種實(shí)現(xiàn),第一個(gè)沒(méi)有使用服務(wù),activity轉(zhuǎn)向后臺(tái)進(jìn)度條消失;另一個(gè)使用服務(wù),activity轉(zhuǎn)向后臺(tái)進(jìn)度條仍然繼續(xù)。
以下是第一個(gè)實(shí)現(xiàn):
主界面布局代碼 notify.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas./apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
-
- <Button
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="開(kāi)始" />
-
- </LinearLayout>
通知欄內(nèi)容布局代碼 notify_content.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas./apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
-
- <ProgressBar
- android:id="@+id/progressBar1"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- android:layout_marginTop="14dp"
- android:layout_toRightOf="@+id/imageView1" />
-
- <TextView
- android:id="@+id/textView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/progressBar1"
- android:layout_marginRight="26dp"/>
-
- <ImageView
- android:id="@+id/imageView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@+id/textView1"
- android:layout_alignParentLeft="true"
- android:src="@drawable/ic_launcher" />
-
- </RelativeLayout>
AndroidManifest.xml 代碼添加如下:
- <activity
- android:label="@string/app_name"
- android:name=".notify.NotificationActivity1" >
- <intent-filter >
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
主程序NotificationActivity1.java代碼如下:
- package com.zhang.new_test.notify;
-
- 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.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.RemoteViews;
- import android.widget.Toast;
-
- import com.zhang.new_test.R;
-
- public class NotificationActivity1 extends Activity implements OnClickListener {
-
- private static final int NOTIFICATION_ID = 0x12;
- private Notification notification = null;
- private NotificationManager manager = null;
- private int _progress = 0;
- private boolean isStop = false;
-
- @Override
- protected void onPause() {
- isStop = false;
- manager.cancel(NOTIFICATION_ID);
-
- super.onPause();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.notify);
-
- Button btn = (Button) findViewById(R.id.button1);
- btn.setOnClickListener(this);
- notification = new Notification(R.drawable.sg, "帶進(jìn)條的提醒", System.currentTimeMillis());
-
- notification.contentView = new RemoteViews(getApplication().getPackageName(), R.layout.notify_content);
- notification.contentView.setProgressBar(R.id.progressBar1, 100, 0, false);
- notification.contentView.setTextViewText(R.id.textView1, "進(jìn)度" + _progress + "%");
-
- notification.contentIntent = PendingIntent.getActivity(this, 0,new Intent(this, NotificationActivity1.class), 0);
-
- manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-
- }
-
- @Override
- public void onClick(View v) {
- isStop = true;
- manager.notify(NOTIFICATION_ID, notification);
- new ProgressThread().start();
- }
-
- private class ProgressThread extends Thread {
-
- @Override
- public void run() {
- while (isStop) {
- _progress += 10;
- Message msg = handler.obtainMessage();
- msg.arg1 = _progress;
- msg.sendToTarget();
-
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- public Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- notification.contentView.setProgressBar(R.id.progressBar1, 100, msg.arg1, false);
- notification.contentView.setTextViewText(R.id.textView1, "進(jìn)度" + msg.arg1 + "%");
- manager.notify(NOTIFICATION_ID, notification);
-
- if (msg.arg1 == 100) {
- _progress = 0;
- manager.cancel(NOTIFICATION_ID);
- isStop = false;
- Toast.makeText(NotificationActivity1.this, "下載完畢", 1000).show();
- }
- }
- };
- }
以下是第二個(gè)實(shí)現(xiàn):
主界面布局代碼 notify.xml和通知欄內(nèi)容布局代碼 notify_content.xml同上一個(gè)實(shí)現(xiàn)
AndroidManifest.xml 代碼添加如下:
- <activity
- android:label="@string/app_name"
- android:name=".notify.NotificationActivity2" >
- <intent-filter >
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <service android:name=".notify.NotificationActivity2$DownLoadService"/>
主程序NotificationActivity2.java代碼如下:
- package com.zhang.new_test.notify;
-
- import android.app.Activity;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.app.Service;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Binder;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.RemoteViews;
- import android.widget.Toast;
-
- import com.zhang.new_test.R;
-
- public class NotificationActivity2 extends Activity implements OnClickListener {
-
- private DownLoadService downLoadService;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.notify);
-
- Button btn = (Button) findViewById(R.id.button1);
- btn.setOnClickListener(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- Intent serviceIntent = new Intent(this,DownLoadService.class);
- startService(serviceIntent);
- bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- unbindService(serviceConnection);
- }
-
- @Override
- public void onClick(View v) {
- downLoadService.startDownLoad();
- }
-
- private ServiceConnection serviceConnection = new ServiceConnection() {
-
- @Override
- public void onServiceConnected(ComponentName name, IBinder service){
- downLoadService = ((DownLoadService.DownLoadServiceBinder) service).getService();
- Toast.makeText(NotificationActivity2.this, "Service Connected.", Toast.LENGTH_LONG).show();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- };
-
- public static class DownLoadService extends Service {
-
- private static final int NOTIFICATION_ID = 0x12;
- private Notification notification = null;
- private NotificationManager manager = null;
- private int _progress = 0;
- private boolean isStop = false;
-
- private Binder serviceBinder = new DownLoadServiceBinder();
-
- @Override
- public void onCreate() {
- super.onCreate();
-
- notification = new Notification(R.drawable.sg, "帶進(jìn)條的提醒", System.currentTimeMillis());
-
- notification.contentView = new RemoteViews(getApplication().getPackageName(), R.layout.notify_content);
- notification.contentView.setProgressBar(R.id.progressBar1, 100, 0, false);
- notification.contentView.setTextViewText(R.id.textView1, "進(jìn)度" + _progress + "%");
-
- notification.contentIntent = PendingIntent.getActivity(this, 0,new Intent(this, NotificationActivity1.class), 0);
-
- manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return serviceBinder;
- }
-
- @Override
- public void onDestroy() {
- isStop = false;
- manager.cancel(NOTIFICATION_ID);
-
- super.onDestroy();
- }
-
- public void startDownLoad() {
- isStop = true;
- manager.notify(NOTIFICATION_ID, notification);
- new ProgressThread().start();
- }
-
- public class DownLoadServiceBinder extends Binder {
- public DownLoadService getService() {
- return DownLoadService.this;
- }
- }
-
- private class ProgressThread extends Thread {
-
- @Override
- public void run() {
- while (isStop) {
- _progress += 10;
- Message msg = handler.obtainMessage();
- msg.arg1 = _progress;
- msg.sendToTarget();
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- public Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- notification.contentView.setProgressBar(R.id.progressBar1, 100, msg.arg1, false);
- notification.contentView.setTextViewText(R.id.textView1, "進(jìn)度" + msg.arg1 + "%");
- manager.notify(NOTIFICATION_ID, notification);
-
- if (msg.arg1 == 100) {
- _progress = 0;
- manager.cancel(NOTIFICATION_ID);
- isStop = false;
- Toast.makeText(DownLoadService.this, "下載完畢", 1000).show();
- }
- }
- };
- }
- }
效果我就不貼圖了,前面提到的鏈接中有,效果差不多。
接下來(lái)分析一下代碼,第二個(gè)和第一個(gè)最大區(qū)別是引入了service,這樣可以支持后臺(tái)運(yùn)行,所以第二個(gè)更有實(shí)用性。但是剛開(kāi)始寫代碼,不應(yīng)該引入服務(wù),那樣會(huì)帶來(lái)過(guò)多的復(fù)雜度,出bug時(shí)很難調(diào)試,寫完第一個(gè)在重構(gòu)引入服務(wù)就沒(méi)那么麻煩了,大部分代碼可以復(fù)用的。
主要知識(shí)點(diǎn)就是Notification和bindService的使用,我主要遇到兩個(gè)悲劇,和大家分享一下:
- 忘了unbindService,拋了一個(gè)不知道的異常,鏈接6解決了
- .notify.NotificationActivity2$DownLoadService 我寫成了 .notify.NotificationActivity2.DownLoadService,鏈接7解決了,這個(gè)花了半天時(shí)間,我就不相信這個(gè)會(huì)錯(cuò),主要是因?yàn)閷懘a時(shí)new 靜態(tài)內(nèi)部類時(shí)都是用 . 啊,忘了配置是用的反射,所以應(yīng)該用 $ 啊,主要是以前沒(méi)寫過(guò)靜態(tài)內(nèi)部類的反射,記住教訓(xùn)了。
希望這篇博文對(duì)大家有幫助。