为什么安卓7.0系统什么手机软件与系统不兼容都不兼容啊?

下载安装APK(兼容Android7.0) - 简书
下载安装APK(兼容Android7.0)
我们使用手机的时候经常会看到应用程序提示升级,大部分应用内部都需要实现升级提醒和应用程序文件(APK文件)下载。
一般写法都差不多,比如在启动app的时候,通过api接口获得服务器最新的版本号,然后和本地的版本号比较,来判断是否需要弹出提示框下载,当然也可以通过推送的自定义消息来实现。
我们这里主要讨论的是应用程序下载,并在通知栏提醒下载完成。实现过程大致分为三步:
创建一个service
在service启动的时候创建一个广播接受者,用于接受下载完成的广播
当BroadcastReceiver接受到下载完成的广播时,开始执行安装。
主要通过系统提供的DownloadManager进行下载,DownloadManager下载完成会发送广播,具体使用看下面完整的代码。如果详细了解可以参考下面创建新的文件DownloadService.java
public class DownLoadService extends Service {
/**广播接受者*/
private BroadcastR
/**系统下载管理器*/
private DownloadM
/**系统下载器分配的唯一下载任务id,可以通过这个id查询或者处理下载任务*/
/**TODO下载地址 需要自己修改,这里随便找了一个*/
private String downloadUrl="/download/daka.apk?v=3.0";
public IBinder onBind(Intent intent) {
public int onStartCommand(Intent intent, int flags, int startId) {
receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
install(context);
//销毁当前的Service
stopSelf();
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
//下载需要写SD卡权限, targetSdkVersion&=23 需要动态申请权限
RxPermissions.getInstance(this)
// 申请权限
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Action1&Boolean&() {
public void call(Boolean granted) {
if(granted){
//请求成功
startDownload(downloadUrl);
// 请求失败回收当前服务
stopSelf();
return Service.START_STICKY;
* 通过隐式意图调用系统安装程序安装APK
public static void install(Context context) {
Intent intent = new Intent(Intent.ACTION_VIEW);
// 由于没有在Activity环境下启动Activity,设置下面的标签
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(
new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "myApp.apk")),
"application/vnd.android.package-archive");
context.startActivity(intent);
public void onDestroy() {
//服务销毁的时候 反注册广播
unregisterReceiver(receiver);
super.onDestroy();
private void startDownload(String downUrl) {
//获得系统下载器
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
//设置下载地址
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downUrl));
//设置下载文件的类型
request.setMimeType("application/vnd.android.package-archive");
//设置下载存放的文件夹和文件名字
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "myApp.apk");
//设置下载时或者下载完成时,通知栏是否显示
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("下载新版本");
//执行下载,并返回任务唯一id
enqueue = dm.enqueue(request);
上面代码使用了RxPermissions第三方库动态申请权限,需要在app/build.gradle文件中进行配置
dependencies {
compile 'com.tbruyelle.rxpermissions:rxpermissions:0.7.0@aar'
compile 'io.reactivex:rxjava:1.1.6' //需要引入RxJava
记得要配置服务
&application
&service android:name=".DownLoadService"/&
&/application&
最后在MainActivity中添加按钮,执行操作。运行结果:
当下载的时候,会有通知栏进度条提示。下载完成会提示安装。不过当前程序如果在Android7.0上就会报错。下面是报错的日志:
Caused by: android.os.FileUriExposedException:
file:///storage/emulated/0/Download/myApp.apk exposed beyond app through Intent.getData()
这是由于Android7.0执行了“StrictMode API 政策禁”的原因,不过小伙伴们不用担心,可以用FileProvider来解决这一问题,
现在我们就来一步一步的解决这个问题。
Android 7.0错误原因
随着Android版本越来越高,Android对隐私的保护力度也越来越大。
比如:Android6.0引入的动态权限控制(Runtime Permissions),Android7.0又引入“私有目录被限制访问”,“StrictMode API 政策”。
这些更改在为用户带来更加安全的操作系统的同时也为开发者带来了一些新的任务。如何让你的APP能够适应这些改变而不是crash,是摆在每一位Android开发者身上的责任。
“私有目录被限制访问“ 是指在Android7.0中为了提高私有文件的安全性,面向 Android N 或更高版本的应用私有目录将被限制访问。这点类似iOS的沙盒机制。
" StrictMode API 政策" 是指禁止向你的应用外公开 file:// URI。 如果一项包含文件 file:// URI类型 的 Intent 离开你的应用,应用失败,并出现 FileUriExposedException 异常。
上面用到的代码中的Uri.fromFile
其实就是生成一个file://URL。
intent.setDataAndType(Uri.fromFile(
new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS),
"myApp.apk")),
"application/vnd.android.package-archive");
一旦我们通过这种办法打开其它程序(这里打开系统包安装器)就认为file:// URI类型的 Intent 离开你的应用。这样程序就会发生异常。
接下来就用FileProvider来解决这一问题。
使用FileProvider
使用FileProvider的大致步骤如下:
第一步:在AndroidManifest.xml清单文件中注册provider,因为provider也是Android四大组件之一,可以简单把它理解为向外提供数据的组件,这种组件在实际开发中用的频率并不高,四大组件都可以在清单文件中进行配置。
&application
android:name="android.support.v4.content.FileProvider"
android:authorities="com.yll520wcf.test.fileprovider"
android:grantUriPermissions="true"
android:exported="false"&
&!--元数据--&
&meta-data
android: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保持一致即可)的资源文件,内容如下:
&files-path/&代表的根目录: Context.getFilesDir()
&external-path/&代表的根目录: Environment.getExternalStorageDirectory()
&cache-path/&代表的根目录: getCacheDir()
上述代码中path="",是有特殊意义的,它代码根目录,也就是说你可以向其它的应用共享根目录及其子目录下任何一个文件了。
如果你将path设为path="pictures",那么它代表着根目录下的pictures目录(eg:/storage/emulated/0/pictures),如果你向其它应用分享pictures目录范围之外的文件是不行的。
第三步:使用FileProvider上述准备工作做完之后,现在我们就可以使用FileProvider了。我们需要将上述安装APK代码修改为如下
public static void install(Context context) {
File file= new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
, "myApp.apk");
//参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致
共享的文件
Uri apkUri =
FileProvider.getUriForFile(context, ".yll520wcf.test.fileprovider", file);
Intent intent = new Intent(Intent.ACTION_VIEW);
// 由于没有在Activity环境下启动Activity,设置下面的标签
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
context.startActivity(intent);
上述代码中主要有两处改变:
将之前Uri改成了有FileProvider创建一个content类型的Uri。
添加了intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);来对目标应用临时授权该Uri所代表的文件。
上述代码通过FileProvider的Uri getUriForFile (Context context, String authority, File file)静态方法来获取Uri该方法中authority参数就是清单文件中注册provider时填写的authority
android:authorities="com.yll520wcf.test.fileprovider"
按照上面步骤修改就可以兼容Android7.0了。
后期修改,之前没有考虑7.0以下的版本
但是如果此程序在Android7.0以下运行又会报错了,我们需要通过版本判断,当Android7.0及以上需要调用上面的代码,Android7.0以下需要调用7.0以下的代码。这样就OK了。修改install() 方法代码。
* 通过隐式意图调用系统安装程序安装APK
public static void install(Context context) {
File file = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
, "myApp.apk");
Intent intent = new Intent(Intent.ACTION_VIEW);
// 由于没有在Activity环境下启动Activity,设置下面的标签
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if(Build.VERSION.SDK_INT&=24) { //判读版本是否在7.0以上
//参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致
共享的文件
Uri apkUri =
FileProvider.getUriForFile(context, "com.a520wcf.chapter11.fileprovider", file);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
context.startActivity(intent);
微信公众账号: likeDev
Android电子书: h...┊      ┊
您现在的位置:> > >
Android 7.0主流应用兼容性问题盘点分析
& & & 什么是应用兼容性问题?比如我们在生活中经常会遇到的应用闪退、无响应、崩溃等问题,在使用QQ等社交软件时偶尔会出现的账号登陆异常问题,这些都是应用不兼容的表现,为广大用户带来了使用上不必要的烦恼。
  对于众多应用开发者以及应用厂商来说,由于这些应用不兼容问题导致的用户体验的缺失,是他们更为头疼和关心的问题,尤其是对于Android 7.0平台上的应用开厂商,新版本的系统更迭升级和功能提升,很可能会导致应用出现各种兼容性问题,所以应用本身针对新版本系统的兼容性测试就显得尤为必要,而目前市场上并没有关于应用兼容性的专业体系的数据分析报告。
  为了验证Android 7.0应用兼容性,为帮助国内开发者及应用厂商尽快适配Android 7.0新版本系统,华为通过对应用市场Top1000主流应用在新版本系统上兼容性表现做了全面专业的测试,对数据进行整理分析,对外正式发布了国内首份应用兼容性测试数据分析报告(简称测试报告)。
  测试报告以应用无响应、启动、闪退崩溃等十种类型不兼容问题为检测依据,对Top1000主流应用进行了专业数据检测,对各类应用兼容率以及数量进行了全面统计,并从常见不兼容问题、不兼容根因等几个方面进行了深入分析,总结出以下四点结论:
 超过10%的应用都中招了,开发者你们还好吗?
  从Andriod 7.0兼容性测试数据结果来看,Top1000主流应用中不兼容应用数量达到166个,导致总体兼容率仅为83%,而Andriod 5.0(L版本)在去年发布后兼容性达到99%,对比之下,这些Andriod 7.0升级之后导致的应用不兼容问题还是比较突出,这也引起广大应用厂商的关注。
  应用不兼容问题Top3,你占了几个?
  正如我们在生活中经常遇到的上述兼容性问题,在此次测试过程中发现,这些问题也是新版本系统下Top1000主流应用避之不及的Bug问题,其中TOP3不兼容问题包括应用启动失败、崩溃、闪退三类,占比高达96.1%,这些Bug问题直接导致了应用出现较差的兼容性表现。
  应用为什么不兼容?原来是加固和权限变化导致的!
  分析报告还指出,导致可能存在兼容问题的两个主要因素,分别是应用本身的加固与谷歌权限的变化,这是常见不兼容问题出现的根因。具体而言(+本站微信networkworldweixin),目前应用市场上的一些金融、银行类、游戏类应用通常会基于安全的考虑,或者由于使用了已经加固后的SDK从而导致不兼容,除此之外还有部分应用是由于Andriod系统本身权限的变化导致的。
  新闻阅读类和游戏类应用兼容率,一个最高一个最低
  经测试报告分析,在参与测试的Top1000应用类别中,新闻阅读类应用的兼容性表现最优,整体通过率达到97.1%,而游戏类应用兼容性表现差的原因正是由于使用的SDK广泛使用了加固技术才导致的,测试中整体通过率仅为63%。
  在对应用兼容通过率进行统计之后,华为还根据通过率高低设置了Android 7.0可兼容应用分类图,应用开发者及厂商可以直观了解自身开发应用兼容性表现如何。
  本次测试发现Android 7.0版本升级给移动应用带来不小影响,主要集中在启动兼容性和稳定性等方面,目前华为已将测试结果正式知会本次不兼容Android 7.0的应用,并给出适配建议,应用开发者可以对新版本进行系统的适配验证,并对应用进行适配优化。
  后续华为将根据兼容率改进情况对参与测试的不兼容应用进行晾晒,督促应用厂商及时适配验证与优化。除此之外,华为还将基于Android 7.0版本各个应用的稳定性、性能、功耗、安全以及接口调用合规等方面发布相关数据分析报告,敬请期待。
上一篇: 下一篇:
【对“Android 7.0主流应用兼容性问题盘点分析”发布评论】
版权及免责声明:
① 本网站部分投稿来源于“网友”,涉及投资、理财、消费等内容,请亲们反复甄别,切勿轻信。本网站部分由赞助商提供的内容属于【广告】性质,仅供阅读,不构成具体实施建议,请谨慎对待。据此操作,风险自担。
② 内容来源注明“硅谷网”及其相关称谓的文字、图片和音视频,版权均属本网站所有,任何媒体、网站或个人需经本网站许可方可复制或转载,并在使用时必须注明来源【硅谷网】或对应来源,违者本网站将依法追究责任。
③ 注明来源为各大报纸、杂志、网站及其他媒体的文章,文章原作者享有著作权,本网站转载其他媒体稿件是为传播更多的信息,并不代表赞同其观点和对其真实性负责,本网站不承担此类稿件侵权行为的连带责任。
④ 本网站不对非自身发布内容的真实性、合法性、准确性作担保。若硅谷网因为自身和转载内容,涉及到侵权、违法等问题,请有关单位或个人速与本网站取得联系(联系电话:),我们将第一时间核实处理。
随着公测版的到来,许多热爱体验的尝鲜者开始蠢蠢欲动,准备将自己的机子刷到iOS 10,……
| Copyright ©
硅谷网 版权所有 网站热线:(+86)010-
WWW.GUIGU.ORG All rights reserved.您的位置: > >
安卓7.0支持那些设备?安卓7.0支持设备一览
发表时间:&&|&&作者:
Android 7.0是谷歌推出的智能手机操作系统,最终官方代号,定名为“Nougat”(牛轧糖)。很多人都在问安卓7.0支持那些设备?下面请看安卓7.0支持设备一览。
谷歌在日凌晨正式放出了Android 7.0的首个测试版本Developer Preview,数据包大小在1.1GB左右。但是如今安卓7.0正式版也马上要出了;那么安卓7.0支持那些设备呢?请看安卓7.0支持设备一览。
支持安卓7.0的Nexus设备包括Nexus 6, Nexus 9, Nexus Player, Nexus 5X, Nexus 6P, Pixel C平板电脑和Android One手机,Nexus 5被抛弃。谷歌表示推送可能需要几周的时间,同时运营商也可能有所阻碍,因此你的手机如果没有立刻收到更新也是正常的。
安卓7.0带来了一系列重要更新,包括升级后的Doze省电功能、新的emoji、更好的快速设置、多窗口支持、通知消息直接回复和多个安全性能提升等。
►小编推荐

我要回帖

更多关于 安装软件与系统不兼容 的文章

 

随机推荐