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; }
相关文章推荐
- Android Butterknife的使用
- Android消息机制Handler的实现原理解析
- Android 时间统计工具,
- Android手机屏幕敲击解锁功能代码
- android NFC学习笔记(基础一)
- Android APK反编译
- Android Crash解决方案之android.view.WindowManager$BadTokenException
- Android菜鸟学步之启动模式
- Android菜鸟学步之Intent
- android开发中常见的几种动画
- Android下面打印进程函数调用堆栈(dump backtrace)的方法
- Android菜鸟学步之Context
- Android菜鸟学步之Service
- 分享简单的数据 Share Simple Data 翻译自developer.android.com
- Android中JNI的使用方法
- Android 开发工具之Codota
- Android sdk content loader 0%的解决方案
- Android之ViewPager的介绍
- Windows Android真机调试无法找到驱动
- Android KitKat 4.4平台开发-添加USB ADB和MTP功能支持