Android(安卓)7.0新特性
Android 7.0新特性
Android: 7.0 行为
移除三项隐式广播
Android 7.0 移除了三项隐式广播
- CONNECTIVITY_ACTION
- ACTION_NEW_PICTURE
- ACTION_NEW_VIDEO
为缓解这些问题,Android 7.0 应用了以下优化措施:
面向 Android 7.0 开发的应用不会收到 CONNECTIVITY_ACTION 广播,即使它们已有清单条目来请求接受这些事件的通知。在前台运行的应用如果使用 BroadcastReceiver 请求接收通知,则仍可以在主线程中侦听 CONNECTIVITY_CHANGE。应用无法发送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 广播。此项优化会影响所有应用,而不仅仅是面向 Android 7.0 的应用。
如果您的应用使用任何 intent,您仍需要尽快移除它们的依赖关系,以正确适配 Android 7.0 设备。Android 框架提供多个解决方案来缓解对这些隐式广播的需求。例如,JobScheduler API 提供了一个稳健可靠的机制来安排满足指定条件(例如连入无限流量网络)时所执行的网络操作。您甚至可以使用 JobScheduler 来适应内容提供程序变化。
使用APK signature scheme v2
Android 7.0(Nougat)引入一项新的应用签名方案APK Signature Scheme v2,它是一个对全文件进行签名的方案,能提供更快的应用安装时间、对未授权APK文件的更改提供更多保护,在默认情况下,Android Gradle 2.2.0插件会使用APK Signature Scheme v2和传统签名方案来签署你的应用。
禁用方法
signingConfigs { release { v2SigningEnabled false } }
美团V2新方案 介绍
传送门:新一代开源Android渠道包生成工具Walle
美团的新的解决方案无法兼容以前的版本
通过对生成渠道号的Apk重新进行签名也是一种解决问题的思路, 只不过打包速度会因为签名,4s一个,对于我来说还是可以接受的
文后附Python源文件。感谢美团提供的思路。
JobScheduler API
Linked https://developer.android.com/reference/android/app/job/JobScheduler.html
JobInfo: 任务数据封装
- JobInfo.Builder JobInfo: 建造者
- JobInfo.TriggerContentUri : 触发条件
- JobParameters : 任务配置参数
- JobScheduler : 应用进程处理JobInfo的调度者
- JobService : 重写onStartJob(JobParameters) 实现自己的业务, 回到方法在主线程,需要异步线程去处理。否则会阻塞onStopJob的调用;
系统权限更改
为了提高私有文件的安全性,面向 Android 7.0 或更高版本的应用私有目录被限制访问 (0700)。此设置可防止私有文件的元数据泄漏,如它们的大小或存在性。此权限更改有多重副作用:
- 私有文件的文件权限不应再由所有者放宽,为使用 MODE_WORLD_READABLE 和/或 MODE_WORLD_WRITEABLE 而进行的此类尝试将触发 SecurityException。
- 传递软件包网域外的 file:// URI 可能给接收器留下无法访问的路径。因此,尝试传递 file:// URI 会触发 FileUriExposedException。分享私有文件内容的推荐方法是使用 FileProvider。
- DownloadManager 不再按文件名分享私人存储的文件。旧版应用在访问 COLUMN_LOCAL_FILENAME 时可能出现无法访问的路径。面向 Android 7.0 或更高版本的应用在尝试访问 COLUMN_LOCAL_FILENAME 时会触发 SecurityException。通过使用 DownloadManager.Request.setDestinationInExternalFilesDir() 或 DownloadManager.Request.setDestinationInExternalPublicDir() 将下载位置设置为公共位置的旧版应用仍可以访问 COLUMN_LOCAL_FILENAME 中的路径,但是我们强烈反对使用这种方法。对于由 DownloadManager 公开的文件,首选的访问方式是使用ContentResolver.openFileDescriptor()。
文件应用之间共享文件异常
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。
要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。
NDK应用链接至平台库
如果您的应用使用动态链接到私有平台 API 的第三方库,您可能也会看到上述 logcat 输出。利用 Android 7.0DK 中的 readelf 工具,您可以通过运行以下命令生成给定 .so 文件的所有动态链接的共享库列表:
更新您的应用
通过下面的一些步骤,您可以修复上述类型的错误并确保您的应用不会在将来的更新版平台上崩溃:
如果您的应用使用私有平台库,您应更新它,以添加该应用自己的库副本或使用公开 NDK API。如果您的应用使用访问私有符号的第三方库,则联系库作者以更新库。请确保将您的所有非 NDK 库与您的 APK 打包在一起。使用标准 JNI 函数而非来自 libandroid_runtime.so 的 getJavaVM 和 getJNIEnv:AndroidRuntime::getJavaVM -> GetJavaVM from AndroidRuntime::getJNIEnv -> JavaVM::GetEnv orJavaVM::AttachCurrentThread from .使用 __system_property_get 而非来自 libcutils.so 的私有 property_get 符号。为此,请使用 __system_property_get 及以下 include 函数:#include 注:系统属性的可用性和内容未通过 CTS 进行测试。应执行进一步修复以避免同时使用这些属性。使用来自 libcrypto.so 的 SSL_ctrl 符号的本地版本。例如,您应在您的 .so 文件中静态链接 libcyrpto.a,或从 BoringSSL/OpenSSL 添加一个动态链接的 libcrypto.so 版本,并将其打包到您的 APK 中。
#!/usr/bin/python# coding=utf-8import zipfileimport shutilimport os# 空文件 便于写入此空文件到apk包中作为channel文件src_empty_file = 'info/czt.txt'# 创建一个空文件(不存在则创建)f = open(src_empty_file, 'w') f.close()# 获取当前目录中所有的apk源包src_apks = []# python3 : os.listdir()即可,这里使用兼容Python2的os.listdir('.')for file in os.listdir('.'): if os.path.isfile(file): extension = os.path.splitext(file)[1][1:] if extension in 'apk': src_apks.append(file)# 获取渠道列表channel_file = 'info/channel.txt'f = open(channel_file)lines = f.readlines()f.close()for src_apk in src_apks: # file name (with extension) src_apk_file_name = os.path.basename(src_apk) # 分割文件名与后缀 temp_list = os.path.splitext(src_apk_file_name) # name without extension src_apk_name = temp_list[0] # 后缀名,包含. 例如: ".apk " src_apk_extension = temp_list[1] # 创建生成目录,与文件名相关 output_dir = 'output_' + src_apk_name + '/' # 目录不存在则创建 if not os.path.exists(output_dir): os.mkdir(output_dir) # 遍历渠道号并创建对应渠道号的apk文件 for line in lines: # 获取当前渠道号,因为从渠道文件中获得带有\n,所有strip一下 target_channel = line.strip() # 拼接对应渠道号的apk target_apk = output_dir + src_apk_name + "-" + target_channel + src_apk_extension # 拷贝建立新apk shutil.copy(src_apk, target_apk) # zip获取新建立的apk文件 zipped = zipfile.ZipFile(target_apk, 'a', zipfile.ZIP_DEFLATED) # 初始化渠道信息 empty_channel_file = "META-INF/cztchannel_{channel}".format(channel = target_channel) # 写入渠道信息 zipped.write(src_empty_file, empty_channel_file) # 关闭zip流 zipped.close() # keyPublish.jks 是你密钥, pass是密码 cmd = 'apksigner sign --ks keyPublish.jks --ks-pass pass:123456 ' + target_apk; p = os.system(cmd) if (p == 0): print('打包成功!') else print(p)
更多相关文章
- android: WheelView组件(滑轮组件)的应用!
- 将war包部署到android服务器上
- Android中自定义属性的格式详解
- context对于android的重要意义
- Android(安卓)Studio 简单介绍和使用问题小结
- Android移动应用基础学习——第四章数据存储
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用