随着市面上8.0的安卓手机日渐增多,我们公司app也要适配到安卓8.0。在适配的过程中,也发现了很多问题,也特此记录一下!

第一个,权限问题。因为我公司的app的 TargetSdkVersion的版本一直是22,(为什么是22,我接手后就是22)所以也没有加入权限适配。所以这一次,我就把公司的TargetSdkVersion的版本改成27,其他什么也都改成27,所以首先解决的就是权限问题。权限问题还是比较好解决,在Gitbub上找了好几个权限适配库,发现还是AndPermission这个权限库比较适合我,而且这个作者也一直在更新!主要是这个库代码风格我比较喜欢。权限问题没什么好说,都是运行中给出权限即可,app需要什么权限,你给它就可以了。这种链式代码风格你喜欢吗?

  private void requestPermission(String... permissions) {AndPermission.with(this).runtime().permission(permissions).rationale(new RuntimeRationale()).onGranted(new Action<List<String>>() {@Overridepublic void onAction(List<String> permissions) {Bundle bundle = new Bundle();bundle.putBoolean("AddDevice", true);openActivity(ScanByZBarActivity.class, bundle);}}).onDenied(new Action<List<String>>() {@Overridepublic void onAction(@NonNull List<String> permissions) {if (AndPermission.hasAlwaysDeniedPermission(getActivity(), permissions)) {showSettingDialog(getActivity(), permissions);}}}).start();}

第二个:在适配的过程中,发现打开app放到哪里,过了一会app就会无缘无故闪退。当然,出现问题,AS肯定是有日志,所以根据日志定位到了StartService()这个代码上。查了资料才明白,安卓8.0之后,系统是不允许后台应用创建后台服务, 因此,Android 8.0 引入了一种全新的方法,即 Context.startForegroundService(),在前台启动新服务。 在系统创建服务后,应用有5秒的时间来调用该服务的 startForeground() 方法以显示新服务的用户可见通知。如果应用在此时间限制内未调用 startForeground(),则系统将停止服务并声明此应用为 ANR。所以这也是为什么app会无缘无故出现闪退的原因。好,知道了这个原因,直接来适配:

Intent intent = new Intent(context, MainService.class);if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {context.startForegroundService(intent);} else {context.startService(intent);}

这里是做了一个判断,当sdk版本>26的时候,就创建一个前台服务,所以app的通知栏会出现一个通知,app在运行中。所以也间接了告诉客户,我这个app在运行中!

第三个问题:通知栏。这次通知栏其实也没有大改,就是加了一个ChanneID,用来允许要为显示的每种通知类型创建用户可自定义的渠道,用户界面将通知渠道称之为通知类别。第一步:获取通知服务 NotificationManager。

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {NotificationChannel channel = new NotificationChannel(Config.CHANNEL_ID, “随便填点啥”, NotificationManager.IMPORTANCE_HIGH);mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);mNotifyManager.createNotificationChannel(channel);} else {mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);}

代码也很简单,也就是判断一下版本。然后获取实列了。

第二步;

  NotificationCompat.Builder builder = null;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {builder = new NotificationCompat.Builder(context, Config.CHANNEL_ID);} else {builder = new NotificationCompat.Builder(context);}builder.setSmallIcon(R.mipmap.logo_notice);builder.setContentTitle(getString(R.string.app_name));builder.setAutoCancel(true);

在这里就是多了一个

    builder = new NotificationCompat.Builder(context, Config.CHANNEL_ID);

这个Channerl_id,可以随便填写。然后其他就是和之前的通知栏就是一样了。

第三个:也是适配安卓7.0的出现的问题。发现app在线升级的时候,升级app没有问题,但是升级之后,打开apk安装发现闪退了。后面查了资料:

Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。

要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。也就是说,对于应用间共享文件这块,Android N中做了强制性要求

<!--加入此权限 8.0系统才能安装apk成功--><uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
 <providerandroid:name=".utils.MyFileProvider"android:authorities="你的包名.fileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_path"tools:replace="name,resource"/></provider>

这里为什么是

  android:name=".utils.MyFileProvider"

而不是:

 android:name="android.support.v4.content.FileProvider"

后面我在来解释。

然后还需要生成一个xml/file_path 文件

<?xml version="1.0" encoding="utf-8"?>
<paths><external-pathname="files_root"path="Android/data/你的包名/"/><external-pathname="external_storage_root"path="."/>
</paths>

打开apk的代码

public static void installApk(Context context, File fileName) {Intent intent = new Intent(Intent.ACTION_VIEW);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);Uri contentUri = FileProvider.getUriForFile(context, "你的包名.fileprovider", fileName);intent.setDataAndType(contentUri, "application/vnd.android.package-archive");} else {intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setAction(Intent.ACTION_VIEW);intent.setDataAndType(Uri.fromFile(fileName), "application/vnd.android.package-archive");}context.startActivity(intent);}

好了,解决上一个问题。

android:name=".utils.MyFileProvider"

因为我的项目中集成了

compile 'com.jph.takephoto:takephoto_library:4.0.3'

如果大家集成了这个项目,就知道了,因为这个项目本身就适配安卓7.0获取应用外部公开 file:// URI,也就是多了,也就多了个FileProvider,所以有冲突,然后还是查了资料,自己重新建了一个类。

public class MyFileProvider extends FileProvider {}

这样就不会冲突了,然后验证一下,升级app之后,果然没有打开apk闪退的原因啦!然后获取相册中的图片设置头像也没有问题了。

好了,这次app适配安卓8.0就到此结束了,其实都还好,在解决的过程中,虽然发现了很多问题,但是后面都慢慢解决了!大家也将自己的app适配到8.0吧! 如果大家在适配的过程有什么问题,也都可以给我留言。

这应该是适配安卓8.0最好的亲身列子了。。。。相关推荐

  1. 华为mate8 android7,华为适配安卓7.0机型除了P9/Mate 8还有它们

    原标题:华为适配安卓7.0机型除了P9/Mate 8还有它们 上周,部分华为P9与Mate 8的升级EMUI 5.0计划已经悄悄展开.微博网友爆料,华为EMUI 5.0的推送开始了.需要强调的是,此次 ...

  2. 氢os android8,不仅只是优化性能 一加氢OS成国内首个适配安卓8.0的系统

    原标题:不仅只是优化性能 一加氢OS成国内首个适配安卓8.0的系统 谈起一加手机,大家除了会想到"不将就"的品牌理念,首先想的就是一加在系统优化方面实力强悍,因为几代一加旗舰产品, ...

  3. 小米5s+刷+android+8.0,小米:正加速为小米5s系列适配安卓8.0

    01小米5s后续也将升安卓8.0 中关村在线消息:近日,小米因迟迟不为小米5s/5s Plus两款机型升级安卓8.0系统,且在升级MIUI 10后很多朋友发现,相较前代系统并没有太大更新,就跟只换了套 ...

  4. [Android多媒体二]调用系统录音机录音并存储到指定位置,适配安卓 7.0

    接上一篇文章,[Android多媒体一]调用系统相机拍照并存储到指定位置,适配安卓 7.0 本文讲述如何调用系统录音机,完成录音后,对录音进行指定位置的保存. 一.开始编写 首先,还是理清一下思路,在 ...

  5. android xbox 手柄,Xbox One手柄将正式适配安卓9.0系统 《堡垒之夜》第一时间支持...

    今天(8月27日)来自谷歌官方消息确认安卓9.0系统即Android Pie将对Xbox One手柄提供完整支持,修复此前长期存在的Xbox One手柄按键映射问题,安卓9.0系统将于今年第3季度起陆 ...

  6. android9.0魅族16,flyme太卡?魅友抢先为魅族16适配安卓9.0,还有MIUI10

    作为魅族今年的逆袭之作,魅族16的发布确实惊艳了不少小伙伴.魅族16系列在设计上使用了无刘海的全面屏设计,首次搭载高通旗舰处理器骁龙845,并配备了光学屏幕指纹识别,顶级索尼IMX380 CMOS等强 ...

  7. Android基础——适配安卓6.0新权限系统

    安卓6.0新权限系统分类 在安卓6.0版本以后,新的权限系统出现了,为了更好的保护用户的安全,新的权限系统需要开发者在代码中手动申请,所以为了适配6.0权限系统,我们不得不学习权限系统 安卓6.0新权 ...

  8. mate9 android8.0 rom,速度逆天 华为Mate9已在适配安卓8.0

    [IT168 资讯]由于与谷歌的深度合作,华为近年在Android系统的更新上更加及时,旗下的Mate 8就曾是国内首款运行Android 6.0系统的手机,目前包括华为Mate 9.P9.P10.荣 ...

  9. mi5s plus android 8.0,小米回应5s/5s Plus迟迟没更新安卓8.0:加速适配

    原标题:小米回应5s/5s Plus迟迟没更新安卓8.0:加速适配 小米回应5s/5s Plus迟迟没更新安卓8.0:加速适配 近日,小编从微博.小米社区及其他网络论坛了解到,因为小米5s和小米5s ...

最新文章

  1. “Python之父”从Dropbox退休
  2. Python的基础,Python的101
  3. R语言ggplot2可视化分面图(faceting)、在所有的分面中添加相同的参考基准曲线(overlay a base or reference plot to all facets )
  4. android fastjson漏洞_【漏洞预警】Fastjson 远程代码执行漏洞(暂无PoC)
  5. 【推荐系统】手写ItemCF/UserCF代码,你会吗?
  6. 什么是OR MAPPING
  7. 常系数齐次线性递推学习笔记
  8. ES6模板字符串【${}配合反单引号一起用】
  9. LinQ—高级查询方法
  10. 华为Mate 50系列明年亮相:或首发高通骁龙898 4G芯片
  11. Visual C++ 图像处理类库CxImage源代码
  12. Android RecyclerView的滚动原理
  13. 基于容器的虚拟化资源调度系统的架构设计
  14. MBP TouchBar自定义使用
  15. react+mobx+jquery构建大型工具项目经验总结
  16. 在linux4.15 移植设备树到JZ2440
  17. CAD中如何绘制带有箭头的引出标注?
  18. 边界函数(decision boundary)
  19. ToG产品_产品运营方案框架_2019_002
  20. 北京苹果店正门logo熄灯悼念 果粉献花纪哀思

热门文章

  1. MT4/MQL4入门到精通EA教程第四课-MQL语言常用函数(四)-K线取值常用函数
  2. 三星v700刷android,三星SM-V700一键救砖教程,轻松刷回官方系统
  3. HttpOnly Cookie 标志
  4. 【毕业设计】危险驾驶行为检测系统(疲劳 抽烟 喝水 玩手机) - opencv python 深度学习
  5. Redis事务控制|相关命令|队列失败两种情况|官方解释无回滚|悲观锁和乐观锁简单介绍
  6. 第3章-14 字符串字母大小写转换 (15 分)
  7. 微软培训 解决ASP.NET TreeView断线问题
  8. Yahoo Email
  9. Barn Repair 修理牛棚,java解题
  10. 【unity技巧】常用技巧