先上图:

首先对android7.0的打开文件方式进行适配

使用FileProvider

第一步:
在AndroidManifest.xml清单文件中注册provider,因为provider也是Android四大组件之一,可以简单把它理解为向外提供数据的组件,这种组件在实际开发中用的频率并不高,四大组件都可以在清单文件中进行配置。

<application...><providerandroid:name="android.support.v4.content.FileProvider"android:authorities="com.example.dl.install"android:grantUriPermissions="true"android:exported="false"><!--元数据--><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider>
</application>

注意:

  • exported:要求必须为false,为true则会报安全异常。
  • grantUriPermissions:true,表示授予 URI 临时访问权限。
  • authorities 组件标识,按照江湖规矩,都以包名开头,避免和其它应用发生冲突。
第二步:指定共享的目录
上面配置文件中  android:resource="@xml/file_paths"  指的是当前组件引用  res/xml/file_paths.xml  这个文件。
我们需要在资源(res)目录下创建一个xml目录,然后创建一个名为“file_paths”(名字可以随便起,只要和在manifest注册的provider所引用的resource保持一致即可)的资源文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"><paths><external-path path="" name="download"/></paths>
</resources>
<files-path/>代表的根目录: Context.getFilesDir()
<external-path/>代表的根目录: Environment.getExternalStorageDirectory()
<cache-path/>代表的根目录: getCacheDir()
上述代码中path="",是有特殊意义的,它代码根目录,也就是说你可以向其它的应用共享根目录及其子目录下任何一个文件了。

如果你将path设为path="pictures",那么它代表着根目录下的pictures目录(eg:/storage/emulated/0/pictures),如果你向其它应用分享pictures目录范围之外的文件是不行的。

第三步:使用FileProvider
上述准备工作做完之后,现在我们就可以使用FileProvider了。会在下个代码块中注释中具体解释

下面是下载安装的具体逻辑

首先在服务中创建DownloadManager

public class DownloadService extends Service {private DownloadFinishReceiver mReceiver;public DownloadService() {}@Overridepublic void onCreate() {super.onCreate();//注册下载完成的广播mReceiver = new DownloadFinishReceiver();registerReceiver(mReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));}@Overridepublic IBinder onBind(Intent intent) {return new DownBinder();}class DownBinder extends Binder{public void startDownload (String downUrl) {//删除已经存在的apk包File apkFile = new File(DownloadService.this.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "小熊.apk");if (apkFile.exists()) {apkFile.delete();}//初始化DownloadManager并开始下载DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downUrl));File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),"小熊.apk");request.setDestinationUri(Uri.fromFile(file));DownloadManager mDownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);mDownloadManager.enqueue(request);}}//下载完成的广播private class DownloadFinishReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {//Android获取一个用于打开APK文件的intentIntent intent1 = new Intent(Intent.ACTION_VIEW);// 由于没有在Activity环境下启动Activity,设置下面的标签intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if(Build.VERSION.SDK_INT>=24) { //判读版本是否在7.0以上//参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件Uri apkUri =FileProvider.getUriForFile(DownloadService.this, "com.example.dl.install",new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),"小熊.apk"));//添加这一句表示对目标应用临时授权该Uri所代表的文件intent1.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent1.setDataAndType(apkUri, "application/vnd.android.package-archive");}else{intent1.setDataAndType(Uri.fromFile(new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),"小熊.apk")),"application/vnd.android.package-archive");}DownloadService.this.startActivity(intent1);}}@Overridepublic void onDestroy() {super.onDestroy();unregisterReceiver(mReceiver);}
}

然后在anctivity中与服务bind绑定 布局文件只有一个按钮来模拟

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btn;private DownloadService.DownBinder binder;private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {binder = (DownloadService.DownBinder) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//与服务连接Intent intent = new Intent(MainActivity.this,DownloadService.class);startService(intent);bindService(intent,connection,BIND_AUTO_CREATE);}private void initView() {btn = (Button) findViewById(R.id.btn);btn.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn:binder.startDownload("http://cdn.xiaoxiongyouhao.com/apps/androilas.apk");break;}}
}

最后添加权限 动态权限前文有使用介绍 这里我没有使用动态权限

  <uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Android 在线下载更新App 下载完成安装APK(兼容Android7.0)相关推荐

  1. 下载安装APK(兼容Android7.0)

    我们使用手机的时候经常会看到应用程序提示升级,大部分应用内部都需要实现升级提醒和应用程序文件(APK文件)下载. 一般写法都差不多,比如在启动app的时候,通过api接口获得服务器最新的版本号,然后和 ...

  2. android 下载apk并自动安装,Android下载apk并自动安装(兼容Android7.0)

    1.开启服务下载新版本 View.OnClickListener checkVersion = new View.OnClickListener () { @Override public void ...

  3. unity调用 Android 分享图片文字 方法 不需要第三方sdk 兼容android7.0+

    直接说方法把,在Android Studio中 新建一个工程,新建时选择Add No Activity,包名跟unity中设置的一样比如这里用 come.demo.share 在res目录下新建个文件 ...

  4. Android开发之下载Apk安装的方法兼容Android7.0和8.0及以上

    具体查看代码: 首先在清单文件配置三个权限读写权限和请求安装权限(兼容Android8.0手机)如下: <!--安装apk权限--><uses-permission android: ...

  5. [Android开发] app在华为手机的应用市场和安装时候显示未兼容android7.0

    一. 图 安装的时候提示不兼容Android7.0 二.原因解决 百度地图的so和jar 库没有更新 和targetapi低于23.... 1. 方法1 (推荐) 更新百度地图的so库和jar包,本来 ...

  6. 96.android 简单的更新APP、下载安装APK(四种方式)

    //第一种 下载更新使用OKHttp+ProgressDialog进度条+第三方AlertDialog //第一步 在Manifest.xml里面写权限: <!-- 网络权限--> < ...

  7. android通知栏自定义软件,android实现通知栏下载更新app示例

    1.设计思路,使用VersionCode定义为版本升级参数. android为我们定义版本提供了2个属性: android:versionCode="1" android:vers ...

  8. Android应用程序更新并下载

    创建一个新类,名为UpdateManager,代码如下: 1 import java.io.BufferedReader; 2 import java.io.File; 3 import java.i ...

  9. Android/ios 如何识别app下载来源追踪

    app推广是公司运营App走向市场的开始,App推广运营人员每天最关心的就是渠道数据的变化,用来衡量工作效果的直接方法.通过不同渠道带来的安装可以区分安装的来源,从而精准定位安装来源,给市场推广和大数 ...

最新文章

  1. hibernate----N-1(一)
  2. 转盘在转动的同时ajax异步加载,用jQuery旋转插件jqueryrotate制作转盘抽奖.pdf
  3. valuestack,stackContext,ActionContext.之间的关系
  4. AOP日志-后置通知
  5. 操作系统基础:存储管理知识笔记(一)
  6. cad钣金展开插件_户外垃圾桶顶盖钣金拆分展开方法
  7. 腾讯宣布五年5000亿投入计划,发力新基建(2020年5月)
  8. 25.使用getScript()方法异步加载并执行js文件
  9. python将多重列表中的成绩按大小输出_Python编程从入门到实践-连载5(字 典)
  10. go语言中函数与方法重要的区别:
  11. 前嗅ForeSpider教程:采集图片/视频/资源文件
  12. Python爬虫反爬方法
  13. 软件工程考研内容有c语言吗,2020中科大软件工程考研初试科目是什么?
  14. 【moment】moment生成日历图及日历事件展示
  15. ICPC 2017 Daejeon-Slot Machines
  16. .netframewor金山卫士推送微软8月补丁 IE所有版本存在高危漏洞
  17. linux 单机安装yum,Linux搭建Nacos服务(单机版)
  18. 【mmaction2 slowfast 行为分析(商用级别)】总目录
  19. 博弈论 (入门)CSU2209 记忆化搜索
  20. 西工大noj(2~10)

热门文章

  1. php xampp教程,xampp教程(一):xampp下载,安装,配置,运行PHP的web项目
  2. 初识 Jetpack Compose
  3. 201621123031 《Java程序设计》第11周学习总结
  4. 小学英语与计算机技术整合,小学英语课程与信息技术的整合
  5. 阿里云负载均衡 SLB CLB 虚拟服务器组配置
  6. 蓝牙室内定位UWB常见场景定位分析
  7. Juniper 命令集合,分好类了,网工收好了哦!
  8. 高效设置的Linux代理效劳器 Squid引见
  9. java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened becaus
  10. Delphi7 提示can‘t load package *.bpl 错误问题的解决方法