入职接手的是一个三年多的老项目,targetSdkVersion
依然是21(...),2019年部分应用市场对targetSdkVersion
做了限制,不得不升级了。
这里记录一些升级到targetSdkVersion=26
时遇到的一些问题。
一、升级targetSdkVersion
到23
- 无需多说,动态权限申请。
-
scrollView
嵌套多个RecyclerView
导致RecyclerView
显示不全。 - UI其他的问题,部分
View
显示不出来,修改xml即可
二、升级targetSdkVersion
到24
问题1:java.lang.UnsupportedOperationException: TextureView doesn't support displaying a background drawable
源码分析:
TextureView
相关源码
@Override
public void setForeground(Drawable foreground) {
if (foreground != null && !sTextureViewIgnoresDrawableSetters) {
throw new UnsupportedOperationException(
"TextureView doesn't support displaying a foreground drawable");
}
}
@Override
public void setBackgroundDrawable(Drawable background) {
if (background != null && !sTextureViewIgnoresDrawableSetters) {
throw new UnsupportedOperationException(
"TextureView doesn't support displaying a background drawable");
}
}
View
相关源码
/**
* Allow setForeground/setBackground to be called (and ignored) on a textureview,
* without throwing
*/
static boolean sTextureViewIgnoresDrawableSetters = false;
// Prior to N, TextureView would silently ignore calls to setBackground/setForeground.
// On N+, we throw, but that breaks compatibility with apps that use these methods.
sTextureViewIgnoresDrawableSetters = targetSdkVersion <= Build.VERSION_CODES.M;
case com.android.internal.R.styleable.View_background:
background = a.getDrawable(attr);
//这里触发了setBackgroundDrawable
if (background != null) {
setBackground(background);
}
public void setBackground(Drawable background) {
//noinspection deprecation
setBackgroundDrawable(background);
}
可以看出,
View
的background
不为null
(不知道原因),且24以后sTextureViewIgnoresDrawableSetters
为false
,会在setBackgroundDrawable
方法中抛出UnsupportedOperationException
异常。
解决方法就是xml
中将背景设置为null
,background
不为null
的原因还未查明
<com.x.xx.xxxTextureView
android:background="@null"
android:layout_width="match_parent"
android:layout_height="match_parent" />
问题2:android.os.FileUriExposedException file exposed beyond app through Intent.getData()
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现
FileUriExposedException
异常。
要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。
例如安装apk对7.0以上需要做判断,同时需要申明权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
public static void installApk(final Context context, final File apkFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data;
String type = "application/vnd.android.package-archive";
//7.0以上需要用
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
data = Uri.fromFile(apkFile);
} else {
String authority = context.getPackageName() + ".fileprovider";
data = FileProvider.getUriForFile(context, authority, apkFile);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.setDataAndType(data, type);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
解决方法:使用FileProvider
,可以参考这篇文章
二、升级targetSdkVersion
到26
Notificaiton通知必须指定Notificaiton Channels
thanks Andriod版本适配 check list
网友评论