您的位置:首页 > 其它

使用ThinDownloadManager下载apk以及notification实时展示进度和安装

2014-11-06 19:35 579 查看
在看这篇总结之前先给出两个牛逼的连接:

1:Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)

url:/article/1970429.html

2:自定义android中的DownloadManager,实现多线程下载Thin DownloadManager is an android library primary to download
files and to avoid usingDOWNLOAD_WITHOUT_NOTIFICATION permission
when using Android provided DownloadManager in your application.
url: https://github.com/yaya2212/ThinDownloadManager

前段时间对我们以前一个app的升级下载功能做了一个优化,把普通的前端下载通过一个通知栏来标示。。效果如下



整个项目包括三个部分:
1:各个布局文件和资源
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dp"
android:text="@string/download1" />

<TextView
android:id="@+id/progressTxt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />

<ProgressBar
android:id="@+id/progress1"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/progressTxt1"
android:layout_marginTop="5dip" />

</LinearLayout>
2: 自定义一个notification的管理类,实现notification中进度的跟新
package com.example.indownloaddemo;

import java.io.File;

import android.app.Notification;
import android.app.NotificationManager;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.NotificationCompat;

/**
*
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉 下载通知定制
*
* @author 14052012
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class EppNotificationControl {

NotificationManager mNotificationManager;
NotificationCompat.Builder mBuilder;
String urlPath;

int progress;
final int NOTIFYCATIONID = 1001;

public EppNotificationControl(String urlPath) {
initNotifycation();
this.urlPath = urlPath;
}

/**
*
* 功能描述: <br>
* 〈功能详细描述〉 初始化一个builder Author: 14052012 zyn Date: 2014年11月6日 下午7:13:14
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
private void initNotifycation() {
mNotificationManager = (NotificationManager) EpaApplication
.getEpaApplication()
.getSystemService(
EpaApplication.getEpaApplication().NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(
EpaApplication.getEpaApplication());
mBuilder.setWhen(System.currentTimeMillis()).setSmallIcon(
R.drawable.ic_launcher);
}

/**
*
* 功能描述: <br>
* 〈功能详细描述〉 首次展示通知栏 Author: 14052012 zyn Date: 2014年11月6日 下午7:13:39
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public void showProgressNotify() {
mBuilder.setContentTitle("等待下载").setContentText("进度:")
.setTicker("开始下载");// 通知首次出现在通知栏,带上升动画效果的
Notification mNotification = mBuilder.build();
mNotification.flags = Notification.FLAG_ONGOING_EVENT;//
// 确定进度的
mBuilder.setProgress(100, progress, false); // 这个方法是显示进度条 设置为true就是不确定的那种进度条效果
mNotificationManager.notify(NOTIFYCATIONID, mNotification);
}

/** 设置下载进度 */
public void updateNotification(int progress) {
Notification mNotification = mBuilder.build();
mNotification.flags = Notification.FLAG_ONGOING_EVENT;//
mBuilder.setProgress(100, progress, false); // 这个方法是显示进度条
mBuilder.setContentText("下载中...").setContentTitle("");
if (progress >= 100) {
mBuilder.setContentText("").setContentTitle("完成");
new Thread(new Runnable() {
public void run() {
Message msg = handler.obtainMessage();
msg.sendToTarget();
}
}).start();

}
mNotificationManager.notify(NOTIFYCATIONID, mNotification);
}

/**
* 异步安装apk
*/
Handler handler = new Handler() {

public void handleMessage(android.os.Message msg) {
Intent apkIntent = new Intent();
apkIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
apkIntent.setAction(android.content.Intent.ACTION_VIEW);
File apkFile = new File(urlPath);
Uri uri = Uri.fromFile(apkFile);
apkIntent.setDataAndType(uri,
"application/vnd.android.package-archive");
EpaApplication.getEpaApplication().startActivity(apkIntent);
mNotificationManager.cancel(NOTIFYCATIONID);// 删除一个特定的通知ID对应的通知
};
};

}
3:使用Activity
package com.example.indownloaddemo;

import java.io.File;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.thin.downloadmanager.DownloadManager;
import com.thin.downloadmanager.DownloadRequest;
import com.thin.downloadmanager.DownloadRequest.Priority;
import com.thin.downloadmanager.DownloadStatusListener;
import com.thin.downloadmanager.ThinDownloadManager;
/**
*
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*  通过多线程来下载apk,同时通过notification来展示进度、下载完成后通过notification自动安装
* @author 14052012
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class MainActivity extends Activity implements OnClickListener {

private ThinDownloadManager downloadManager;
//下载的线程数
private static final int DOWNLOAD_THREAD_POOL_SIZE = 4;

Button mDownload1;

ProgressBar mProgress1;

TextView mProgress1Txt;
Context context;

/**
* 服务端apk路径
*/
private static final String FILE1 = "http://app.suning.com/d.php?pack=com.suning.mobile.epa";

MyDownloadListner myDownloadStatusListener = new MyDownloadListner();

int downloadId1 = 0;
private DownloadRequest request1;

EppNotificationControl notificationControl;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
createSDCardDir("epp.apk");
initView();
initDownload();
notificationControl = new EppNotificationControl(this.urlPath);
}

private void initDownload() {
Uri downloadUri = Uri.parse(FILE1);
Uri destinationUri = Uri.parse(urlPath);
Log.i("jone", urlPath);
request1 = new DownloadRequest(downloadUri)
.setDestinationURI(destinationUri).setPriority(Priority.HIGH)
.setDownloadListener(myDownloadStatusListener);

}

private void initView() {

mDownload1 = (Button) findViewById(R.id.button1);

mProgress1Txt = (TextView) findViewById(R.id.progressTxt1);

mProgress1 = (ProgressBar) findViewById(R.id.progress1);

mProgress1.setMax(100);
mProgress1.setProgress(0);

downloadManager = new ThinDownloadManager(DOWNLOAD_THREAD_POOL_SIZE);
mDownload1.setOnClickListener(this);

}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
if (downloadManager.query(downloadId1) == DownloadManager.STATUS_NOT_FOUND) {
downloadId1 = downloadManager.add(request1);
}
mProgress1Txt.setText("Download1");
// showProgressNotify();
notificationControl.showProgressNotify();
break;
}
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
downloadManager.release();
}

class MyDownloadListner implements DownloadStatusListener {

@Override
public void onDownloadComplete(int id) {
Log.i("jone", "download completed");
if (id == downloadId1) {
mProgress1Txt.setText("Download1 id: " + id + " Completed");
}
}

@Override
public void onDownloadFailed(int id, int errorCode, String errorMessage) {
Log.i("jone", "DownloadFailed");
if (id == downloadId1) {
mProgress1Txt.setText("Download1 id: " + id
+ " Failed: ErrorCode " + errorCode + ", "
+ errorMessage);
mProgress1.setProgress(0);
}
}

@Override
public void onProgress(int id, long totalBytes, long downloadedBytes,
int progress) {

Log.i("jone", progress + "");
if (id == downloadId1) {
mProgress1Txt
.setText("Download1 id: " + id + ", " + progress + "%"
+ "  "
+ getBytesDownloaded(progress, totalBytes));
mProgress1.setProgress(progress);
// setNotify(progress);
notificationControl.updateNotification(progress);
}

}
}

private String getBytesDownloaded(int progress, long totalBytes) {
// Greater than 1 MB
long bytesCompleted = (progress * totalBytes) / 100;
if (totalBytes >= 1000000) {
return (""
+ (String.format("%.1f", (float) bytesCompleted / 1000000))
+ "/"
+ (String.format("%.1f", (float) totalBytes / 1000000)) + "MB");
}
if (totalBytes >= 1000) {
return ("" + (String.format("%.1f", (float) bytesCompleted / 1000))
+ "/" + (String.format("%.1f", (float) totalBytes / 1000)) + "Kb");

} else {
return ("" + bytesCompleted + "/" + totalBytes);
}
}

String urlPath;

public String createSDCardDir(String name) {
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
File sdcardDir = Environment.getExternalStorageDirectory();
String path = sdcardDir.getPath() + "/MUDOWN";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir + File.separator + name);
if (!file.exists()) {
try {
file.createNewFile();
} catch (Exception e) {
}
urlPath = file.getPath();
}
}
return urlPath;
}
}

整个过程我都有说明,使用了开源库ThinDownloadManager,大家可以到github上仔细看看源码
最后附上我的demo

http://download.csdn.net/detail/yaya_soft/8129205 这个版本是在ui页面发的请求

http://download.csdn.net/detail/yaya_soft/8132483 这个版本是通过IntentService来实现的【推荐使用版本】

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: