您的位置:首页 > 移动开发 > Android开发

android 利用dwonLoadManager 实现apk下载更新

2016-07-05 10:32 399 查看

项目之前一直用的友盟的自动更新,但好像友盟那边10月份就开始不支持软件更新了,所以把更新的功能做到自己的服务器上面。

基本的实现思路如下:

1. 后台可以提供一个接口也可以,就是我们将当前的版本传过去,然后后台返回是否需要更新,如果需要,给出url,

2. 下载apk

3. 安装apk

具体实现:

1. 向服务器请求的结果如下

{
status: 1,
msg: "需要更新",
versionCode:1
updateUrl: "http://www.ejoooo.com/app/com.ejooo.jianli.apk"
}


后台已经帮我们判断了是否需要更新,我们只需要根据status的状态来判断是否做出进一步的操作。versionCode的作用是用来判断用户本地是否下载了最新的apk,避免重复下载。

2. 我是向后台请求数据后,弹出一个询问是否需要更新的对话框,点击确定操作后

Intent intent = new Intent(mContext.getApplicationContext(), DownLoadService.class);
intent.putExtra(UpdateConstants.FIELD_APK_DOWNLOAD_URL, VALUE_DOWNLOAD_URL);
intent.putExtra(UpdateConstants.FIELD_APK_NAME, appName);
intent.putExtra(UpdateConstants.FIELD_APK_PATH, mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getPath());
mContext.startService(intent);


3.这里需要注意的是

DownLoadService 不可集成IntentService,不然写在IntentService里面的BroadCastRecieve接收不到广播。

public class DownLoadService extends Service {
public static long DOWNLOAD_ID;
private String downloadUrl;
private String apkName;
private String apkPath;
/**
* 安卓系统下载类
**/
DownloadManager manager;

/**
* 接收下载完的广播
**/
DownloadCompleteReceiver receiver;

/**
* 初始化下载器
**/
private void initDownManager() {

manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

receiver = new DownloadCompleteReceiver();

List<String> list = FileUtils.GetFiles(apkPath, "apk", apkName, false);
if (list.size() != 0) {
installAPK(Uri.fromFile(new File(list.get(0))));
return;
}

//设置下载地址
DownloadManager.Request down = new DownloadManager.Request(
Uri.parse(downloadUrl));

// 设置允许使用的网络类型,这里是移动网络和wifi都可以
down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
| DownloadManager.Request.NETWORK_WIFI);

// 下载时,通知栏显示途中
down.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

// 显示下载界面
down.setVisibleInDownloadsUi(true);

// 设置下载后文件存放的位置
down.setDestinationInExternalFilesDir(this,
Environment.DIRECTORY_DOWNLOADS, apkName + ".apk");

// 将下载请求放入队列
DOWNLOAD_ID = manager.enqueue(down);

//注册下载广播
registerReceiver(receiver, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

downloadUrl = intent.getStringExtra(UpdateConstants.FIELD_APK_DOWNLOAD_URL);
apkName = intent.getStringExtra(UpdateConstants.FIELD_APK_NAME);
apkPath = intent.getStringExtra(UpdateConstants.FIELD_APK_PATH);
// 调用下载
initDownManager();

return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind(Intent intent) {

return null;
}

@Override
public void onDestroy() {

// 注销下载广播
if (receiver != null)
unregisterReceiver(receiver);

super.onDestroy();
}

/**
* 安装apk
* @param apk
*/
private void installAPK(Uri apk){
Intent intent = new Intent();
//执行动作
intent.setAction(Intent.ACTION_VIEW);
//执行的数据类型
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(apk, "application/vnd.android.package-archive");
//不加下面这句话是可以的,查考的里面说如果不加上这句的话在apk安装完成之后点击单开会崩溃
//android.os.Process.killProcess(android.os.Process.myPid());
startActivity(intent);
}

// 接受下载完成后的intent
class DownloadCompleteReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
//判断是否下载完成的广播
if (intent.getAction().equals(
DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {

//获取下载的文件id
long downId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, -1);

//自动安装apk
installAPK(manager.getUriForDownloadedFile(downId));

//停止服务并关闭广播
DownLoadService.this.stopSelf();

}
}

/**
* 安装apk文件
*/
private void installAPK(Uri apk) {

// 通过Intent安装APK文件

Intent intent = new Intent();
//执行动作
intent.setAction(Intent.ACTION_VIEW);
//执行的数据类型
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(apk, "application/vnd.android.package-archive");
//不加下面这句话是可以的,查考的里面说如果不加上这句的话在apk安装完成之后点击单开会崩溃
//android.os.Process.killProcess(android.os.Process.myPid());
startActivity(intent);

}

}
}


4.如何实现避免用户重复下载的问题

具体的实现方法是通过文件查找的方法,查找下载目录下面是否有最新的apk。至于apk是否为最新的,就需要在下载的时候通过versionName+versionCode命名,更新的时候从无夫妻获取到最新的versionCode 与文件名称做比较即可。

/**
* 查找文件
*
* @param Path        文件夹路径
* @param Extension   文件扩展名
* @param IsIterative 是否进入子文件夹
*/
public static List<String> GetFiles(String Path, String Extension, String fileName, boolean IsIterative) //搜索目录,扩展名,是否进入子文件夹
{
List<String> lstFile = new ArrayList<String>(); //结果 List
File[] files = new File(Path).listFiles();
if (files == null) {
return lstFile;
}
for (int i = 0; i < files.length; i++) {
File f = files[i];
if (f.isFile()) {
if (f.getPath().substring(f.getPath().length() - Extension.length()).equals(Extension)) { //判断扩展名
String name =files[i].getName();
if (files[i].getName().equals(fileName+".apk")) {
lstFile.add(f.getPath());
}
}
/*if (!IsIterative)
break;*/
} else if (f.isDirectory() && f.getPath().indexOf("/.") == -1) //忽略点文件(隐藏文件/文件夹)
GetFiles(f.getPath(), Extension, fileName, IsIterative);
}
return lstFile;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: