前言
Android版本现在更新的越来越快,搞得开发者适配起来很烦,往往稍不注意就踩坑了,本篇博客主要用来记录Android版本行为不同带来的坑(踩到更新)
各个版本更改文档:https://developer.android.google.cn/about/versions
5.0(API 21)
1.绑定服务
Context.bindService() 方法现在需要显式 Intent,如果提供隐式 intent,将引发异常。个人测试在一些版本上面使用Context.startService()也会引发异常。
现象:
ava.lang.IllegalArgumentException: Service Intent must be explicit:
解决方法:
设置包名
Intent intent = new Intent(KEY_ACTION); intent.setPackage(KEY_PKG_NAME); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
使用显示Intent
Intent intent = new Intent(); intent.setAction("com.serverdemo.action"); intent.setComponent(new ComponentName("com.serverdemo", "com.serverdemo.CustomService"));
或者将隐式Intent修改为显示Intent:Stack Overflow
public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { // Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0); // Make sure only one match was found if (resolveInfo == null || resolveInfo.size() != 1) { return null; } // Get component info and create ComponentName ResolveInfo serviceInfo = resolveInfo.get(0); String packageName = serviceInfo.serviceInfo.packageName; String className = serviceInfo.serviceInfo.name; ComponentName component = new ComponentName(packageName, className); // Create a new intent. Use the old one for extras and such reuse Intent explicitIntent = new Intent(implicitIntent); // Set the component to be explicit explicitIntent.setComponent(component); return explicitIntent; }
getRecentTasks()被弃用
现象:
在Android5.0上,处于用户隐私考虑,谷歌将其行为进行了修改,只能获取到自己本身或者一些不重要的数据比如桌面等。
解决方案
可以使用这个库:AndroidProcesses、或者看你的脑洞有多大,也可以参看:参考链接
6.0(API 23)
动态权限申请
当你的apk targetSdkVersion >= 23的时候。对于某些权限需要进行动态申请。
现象:java.lang.SecurityException: Permission Denial:
解决办法:http://27house.cn/archives/1012
7.0(API 24)
1、在应用间分享文件出现FileUriExposedException
Android N上面不允许分享file://链接到其他应用,需要使用FileProvider
解决办法:http://27house.cn/archives/1339
2、网络变化广播只能使用动态广播监听
如果要监听CONNECTIVITY_ACTION广播(网络变化),必须使用动态广播,7.0上面使用静态广播将不生效。
3、Https CA证书
7.0开始,系统默认不信任非系统CA,更多可以查看Android 7.0新增之网络安全性配置
8.0(API 26)
1、Notification必须设置Channel
解决办法:http://27house.cn/archives/1410
2、Android 8.0启动系统默认安装界面需要额外申请权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
3、Android 8.0启动后台服务崩溃
java.lang.IllegalStateException:Not allowed to start service Intent { cmp=class-name }: app is in background uid UidRecord{6ed2d08 u0a171 CAC bg:+2m25s792ms idle procs:2 seq(0,0,0)}
在8.0上面,当应用处于后台的时候不允许启动后台服务,不然会出现上面的错误。8.0 及以上需要使用 Context.startForegroundService()启动前台服务。在服务创建后,应用有五秒的时间来调用该服务的 startForeground() 方法以显示新服务的用户可见通知。如果应用在此时间限制内未调用 startForeground(),则系统将停止服务并声明此应用为 ANR。同样的,需要设置Channel
4、8.0继续限制静态广播
在8.0上面,大多数静态广播不可用,所以我们需要使用动态注册,如果我们需要进行接收到广播以后的处理,我们也许可以使用JobScheduler
9.0(API 28)
1、使用前台服务需要申请FOREGROUND_SERVICE权限,这个权限是普通权限,如果不申请权限就直接启动前台服务会抛SecurityException
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
2、应用在后台无法启动Activity,不管你的target SDK是多少都会生效
参考链接:https://juejin.im/post/5ce8b612f265da1b614fd30e#heading-7
10.0(API 29)
1、WIFI的mac地址默认使用随机mac。文档地址
2、除非应用是默认输入法 (IME) 或是目前处于焦点的应用,否则它无法访问 Android 10 或更高版本平台上的剪贴板数据。适配方案
3、对 /proc/net 文件系统的访问权限实施了限制。参考
4、Android 深色模式适配 文档地址
HELLO WORLD!
@黑老 what are you 弄啥捏