美文网首页Android开发差异化7.0Android技术知识
兼容Android 6.0,您需要做的几件事儿!

兼容Android 6.0,您需要做的几件事儿!

作者: zsmiling | 来源:发表于2017-04-25 18:38 被阅读382次

    目前谷歌已经放出了Android O(8.0)的预览版,但很多app并没有使用6.0以来的新特性。下面就结合官方文档和自己工作中需要的一些问题,简单总结了下,在对您的应用进行针对target23以其以上重构时,需要注意和兼容的问题。

    一,低耗电模式。

    Android 6.0(API 级别 23)引入了低电耗模式,当用户设备未插接电源、处于静止状态且屏幕关闭时,该模式会推迟 CPU 和网络活动,从而延长电池寿命。而 Android 7.0 则通过在设备未插接电源且屏幕关闭状态下、但不一定要处于静止状态(例如用户外出时把手持式设备装在口袋里)时应用部分 CPU 和网络限制,进一步增强了低电耗模式。

    A.网络访问的限制

    在涉及到网络访问,特别时后台访问网络的,需要测试下,在低耗电模式下,应用是否执行正常,会不会anr或者崩溃

    B.后台唤醒机制

    即对齐唤醒,主要涉及到的是WakeLockAlarm,后台的一些定时服务,可能会不准

    二,后台优化

    Android 7.0移除了三项隐式广播,以帮助优化内存使用和电量消耗。此项变更很有必要,因为隐式广播会在后台频繁启动已注册侦听这些广播的应用。删除这些广播可以显著提升设备性能和用户体验。

    A. CONNECTIVITY_ACTION

    面向 Android 7.0 开发的应用不会收到CONNECTIVITY_ACTION广播,即使它们已有清单条目来请求接受这些事件的通知。在前台运行的应用如果使用BroadcastReceiver请求接收通知,则仍可以在主线程中侦听CONNECTIVITY_CHANGE。

    B. ACTION_NEW_PICTURE

    C. ACTION_NEW_VIDEO

    应用无法发送或接收ACTION_NEW_PICTUREACTION_NEW_VIDEO广播。此项优化会影响所有应用,而不仅仅是面向 Android 7.0 的应用。

    三,权限更改

    A.私有文件的文件权限不应再由所有者放宽,为使用MODE_WORLD_READABLE和/或MODE_WORLD_WRITEABLE而进行的此类尝试将触发SecurityException。

    B.当你跨package域传递file://的URI时,接收者得到的将是一个无权访问的路径,将会触发FileUriExposedException。官方推荐的方式是使用FileProvider,也可以使用ContentProvider

    Eg:调用系统相机拍照并存入指定路径中

    Api24之前,可以这样

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri uri = Uri.fromFile(sdcardTempFile);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

    Target=24时,会报crash FileUriExposedException

    Target24上的正确方法是:

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); ContentValues contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, sdcardTempFile.getAbsolutePath());

    Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);

    或者使用FileProvider方式

    这块儿,分享模块或者其他有 调起三方应用并给其传递我们应用理解的图片等文件资源的话,会存在这个问题。这块儿有个帖子写到了他们的解决办法

    http://www.jianshu.com/p/68a4e8132fcd

    四,屏幕缩放

    Android 7.0 支持用户设置显示尺寸,以放大或缩小屏幕上的所有元素,从而提升设备对视力不佳用户的可访问性。用户无法将屏幕缩放至低于最小屏幕宽度

    在android N上,Setting多了一个Display size设置,更改这个属性,系统会以如下方式通知正在运行的应用:

    A.如果是面向API级别23或更低版本系统的应用,系统会自动终止其所有后台进程。这意味着如果用户切换离开此类应用,转而打开Settings屏幕并更改Display size设置,则系统会像处理内存不足的情况一样终止该应用。如果应用具有任何前台进程,则系统会如处理运行时更改中所述将配置变更通知给这些进程,就像对待设备屏幕方向变更一样。

    B.如果是面向Android 7.0的应用,则其所有进程(前台和后台)都会收到有关配置变更的通知

    在这里,需要测试这几个方面的问题:

    a.界面显示问题,既在用户更改了这个属性时,整个界面元素的大小都会变化,需要测试此时我们的界面是否ok

    b.当设备配置发生变更时,更新任何与密度相关的缓存信息

    五,NDK应用链接至平台库

    从 Android 7.0 开始,系统将阻止应用动态链接非公开 NDK 库,这种库可能会导致您的应用崩溃。

    即使您的代码可能不会链接私有库,但您的应用中的第三方静态库可能会这么做。因此,所有开发者都应进行相应检查,确保他们的应用不会在运行 Android 7.0 的设备上崩溃。

    Logcat会给我们一些提示。

    应用面向 API 级别 24 或更高级别,logcat 会生成以下运行时错误,您的应用可能会崩溃:

    java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"

    ("/system/lib/libcutils.so") needed or dlopened by

    "/system/lib/libnativeloader.so" is not accessible for the namespace

    "classloader-namespace"

    at java.lang.Runtime.loadLibrary0(Runtime.java:977)

    at java.lang.System.loadLibrary(System.java:1602)

    利用 Android 7.0DK 中的 readelf 工具,您可以通过运行以下命令生成给定.so文件的所有动态链接的共享库列表:

    aarch64-linux-android-readelf -dW libMyLibrary.so

    六,Android for Work

    可以使用DevicePolicyManagewr.getWifiMacAddress()访问设备的 WLAN MAC 地址。如果设备上从未启用 WLAN,则此方法将返回一个null值。

    七,权限,重要的权限需要授权。

    网上很多开源的授权工具类,例如这个

    https://github.com/opengit/MonkeyAndroid/blob/master/app/src/main/java/com/sunjiajia/monkeyandroid/utils/PermissionsUtil.java

    八,其他

    悬浮窗授权。 很多时候程序里面有在当前界面弹出一个授权窗口,引导用户去授权或者开启辅助选项等。在api24上,需要对在当前页面弹窗这一动作授权

    Note:If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen. The app requests the user's approval by sending an intent with actionACTION_MANAGE_OVERLAY_PERMISSION. The app can check whether it has this authorization by callingSettings.canDrawOverlays().

    Constant Value: "Android.permission.SYSTEM_ALERT_WINDOW"

    代码如下:

    if (Build.VERSION.SDK_INT >= 23) {

    if(!Settings.canDrawOverlays(getApplicationContext())) {

    //启动Activity让用户授权

    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);

    startActivity(intent);

    return;

    } else {

    //执行6.0以上绘制代码

    }

    } else {

    //执行6.0以下绘制代码

    }

    相关文章

      网友评论

        本文标题:兼容Android 6.0,您需要做的几件事儿!

        本文链接:https://www.haomeiwen.com/subject/kwyhhttx.html