Android 7.0适配
1:权限更改
2:低功耗.
3:后台优化
4:应用间文件共享:
5:通知栏
6:屏幕缩放
7:NDK平台库
8:其他
分析:
1)权限管理:随着Android版本越来越高,Android对隐私的保护力度也越来越大。从Android6.0引入的动态权限控制(Runtime Permissions)到Android7.0的“私有目录被限制访问”,“StrictMode API 政策”。这些更改在为用户带来更加安全的操作系统的同时也为开发者带来了一些新的任务,因为无情的crash。
权限问题,7.0上面的权限要动态申请,需要用户手动点击允许使用才能打开对应的权限,如果不动态申请,直接用会崩溃。一般使用第三方的库permissionsdispatcher,先介绍如何使用
1:github开源地址: https://github.com/hotchemi/PermissionsDispatcher
2: 工程项目的:build.gradle
dependencies {
classpath ‘com.android.tools.build:gradle:2.2.3’
classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}在依赖中添加了一项插件。
app模块的build.gradle
apply plugin: ‘com.android.application’
apply plugin: ‘android-apt’
在依赖jar中添加
dependencies {
compile fileTree(dir: ‘libs’, include: [‘*.jar’])
compile ‘com.github.hotchemi:permissionsdispatcher:2.3.1’//github的权限管理
apt ‘com.github.hotchemi:permissionsdispatcher-processor:2.3.1’
}
并将targetSdkVersion设为23,即:targetSdkVersion 23,或者23以上都可以。buildToolsVersion ‘23.0.0’以上,23以下的话会直接给出权限。
配置好之后,如何使用,先sync一下,把相关的jar下载下来
具体使用方式如下:
接下来生成中间文件。编译方式如下图(左边),编译之后就会生成右边的文件。
文件生成之后就可以调用了,在哪里调用了,就是在需要的时候,例如这个测试程序启动就要开启GPS定位,所以直接写在onCreate()里,如下
在添加上回调
运行之后就会弹出提出匡。询问是否允许开启权限
在来看看需要注意的地方:Activity必须继承AppCompatActivity,在Activiy前面添加注解@RuntimePermissions。在方法startGpsLocation()前面添加需要权限的注释,另外两个方法一个是用户点击了拒绝以及下次不在询问之后要怎么做的方法。
在整体看下有哪些注释,先看定义
Annotation Required Description
@RuntimePermissions ✓ 注解在其内部需要使用运行时权限的Activity或Fragment上
@NeedsPermission ✓ 注解在需要调用运行时权限的方法上,当用户给予权限时会执行该方法
@OnShowRationale 注解在用于向用户解释为什么需要调用该权限的方法上,只有当第一次请求权限被用户拒绝,下次请求权限之前会调用
@OnPermissionDenied 注解在当用户拒绝了权限请求时需要调用的方法上
@OnNeverAskAgain 注解在当用户选中了授权窗口中的不再询问复选框后并拒绝了权限请求时需要调用的方法,一般可以向用户解释为何申请此权限,并根据实际需求决定是否再次弹出权限请求对话框
可以看到前面两个注释是必须使用的。
还有就是在没有申请权限之前,运行需要权限的代码会直接报错。所以写代码的时候要明白那些权限需要申请,那些不需要,还有一个疑问就是GPS开启定位的权限应该有好几个,为什么代码中只申请了一个。
看看官方的说明分类
这个表里面的权限称为危险权限列表,这些权限是需要运行时申请,没有列出来的就不需要,还是和以前一样在Menifests里面定义就可以了,当然危险权限也是要写的。从表中可以看出是权限有分组的,分组的意义在于组内的一个权限被申请,其他权限系统自动就分配了,所以只需要申请一组中的其中一个权限就可以。提示下定位的权限,在高版本上面申请完成之后并不会打开,而是需要用户手动开启,也无法通过代码关闭。
2)低功耗的问题:
官方解析:Android 6.0(API 级别 23)引入了低电耗模式,当用户设备未插接电源、处于静止状态且屏幕关闭时,该模式会推迟 CPU 和网络活动,从而延长电池寿命。而 Android N 则通过在设备未插接电源且屏幕关闭状态下、但不一定要处于静止状态(例如用户外出时把手持式设备装在口袋里)时对 CPU 和网络限制,进一步增强了低电耗模式。
具体表现如下:
在设备处于电池状态时屏幕关闭后很短时间,Doze(低功耗模式)限制网络访问并延迟作业和同步。如果进入低电耗模式后设备处于静止状态达到一定时间,系统则会对 PowerManager.WakeLock、AlarmManager 闹铃、GPS 和 WLAN 扫描应用余下的低电耗模式限制。无论是应用部分还是全部低电耗模式限制,系统都会唤醒设备以提供简短的维护时间窗口,在此窗口期间,应用程序可以访问网络并执行任何被推迟的作业/同步。打开屏幕或插入设备会使设备脱离Doze。
看官方提供的图:
想一下对我们开发有什么影响,拿 GPS来说,当开启一个GPS服务来请求地址位置,会有什么影响?当设备处于电池耗电,并且关闭屏幕一定时间之后,GPS服务关闭掉了。直接用上面的代码测试就可以测试出来,在7.0上面GPS的定位结果和上图是一致的。所以写代码的时候要注意开启和关闭的时机。
随便提一下,高德地图的API,高德地图最新API中有启动一个闹钟定时唤醒CPU,通过AlarmManager来发送广播,接受到就启动定位。首先通过上图就可以看出Alarm是一个非准确传递的。其次Doze模式的第二阶段GPS已经被关闭了,感觉是没有用的,但是我测试下来,是有用的,因为用的是网络定位,没网络高德Demo中这个方案是运行不了。在Doze模式下大概是没9分钟执行一次alram。
在实际开发中,如果仅仅使用GPS定位,频繁定位,代码中两秒定位一次,在屏幕亮起的时候,一直定位,会被android系统弹框提示耗电异常,多长时间定位了多少次,是否优化,用户只要点击了确定,应用就会杀死。所以在GPS定位中一定要在7.0上面多去验证。初步结论就是要延长,定位的时间间隔,以及定位距离。但是具体多长的也没有验证出来,主要是手机是借的,我的手机上面不会弹框,估计被优化了。这里再提下高德的API,因为在验证这个问题的时候一直都是在拿着高德demo来同步验证的,主要看这个图:
测试的结果:高德定位默认配置混合定位,速度很快1-3s,前提条件是有网络,当网络定位失败或者超时(30s),才会开启GPS定位。关闭网络,仅选择GPS高精度定位用时30-60s。从Demo中可以看出来,高德地图的GPS定位只会作为网络定位提高精度的辅助。例如使用高德地图APP,当网络关闭,GPS打开的时候,是打不开的,也无法定位,类似的还有ofo,摩拜等APP都是的如此,没有网络进不去APP,有网络,GPS关闭的时候可以使用APP,只是提示打开GPS定位更精准。
对于GPS还有一点需要注意的是:
不安全的地理位置(Geolocation on insecure origins)
以Android 7.0为目标的应用开始,地理位置API将只允许在安全来源(通过HTTPS)。此政策旨在保护用户在使用不安全连接时的私人信息。其实不止地理位置,在Android 7.0 中,通过使用说明性“网络安全性配置”(而不是使用传统的易出错的编程 API(例如,X509TrustManager)),应用可以安全地自定义其安全(HTTPS、TLS)连接的行为,无需任何代码修改。其实这段话我自己看的也不是很明白,能确定的就是第一HTTP的协议google认为有必要修改到https,第二:如果你的APP是类似于浏览器的APP,你可以在开发的时候配置各种安全的证书,只要是没有获取安全证书的网站,通过你的APP是没法连接上服务器的,配置都是通过Android 的xml文件来完成的,不需要写额外的代码。
3)Project Svelte:后台优化
Android 7.0 移除了三项隐式广播,以帮助优化内存使用和电量消耗。因为隐式广播会在后台频繁启动已注册侦听这些广播的应用。删除这些广播可以显著提升设备性能和用户体验。三项广播分别为CONNECTIVITY_ACTION,ACTION_NEW_PICTURE,ACTION_NEW_VIDEO 。分别开看一下对开发的影响.
CONNECTIVITY_ACTION监听网络变化的广播,不能静态注册监听,但是可以在Activity中动然注册监听。影响不大。官方给出的解决方案是JobScheduler,一个新的网络任务调度API,网上也有很多例子了。需要注意的是7.0新增加了DATA SAVE数据节约功能,可能会影响到网络的使用,当用户开启的这个功能,并使用APP的时候,要注意提示用户,或者引导用户把应用加入到白名单中。有对于的API可以设置。ConnectivityManager的扩展功能就是做这些事情的。
ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO这两个广播APP是无法再发送和接受的,好像没什么影响,这两个广播好早就没有用了,我们的APP中刷新图片到SD中显示用的都是ACTION_MEDIA_SCANNER_SCAN_FILE。
4)应用间文件共享:
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。
同样上面的一段也是官网的解释,首先是严格模式默认执行的,文件是私有的,外部应用不能访问。很显然对调用系统相机,分享是有影响的,因为这都是把文件给别的应用去访问。
直接看解决方案:
第一步:在android menifests里面添加provider