Android target sdk升级到28遇到的问题 - xiaoniudonghe2015/Android-Java-Code-Style GitHub Wiki
1.项目target从26升级到28遇到的问题
1.1 在9.0上出现java.lang.SecurityException: Permission Denial: startForeground from pid=32221, uid=10642 requires android.permission.FOREGROUND_SERVICE
原因:
针对 Android 9 或更高版本并使用前台服务的应用必须请求 FOREGROUND_SERVICE 权限。 如果针对 Android 9 或更高版本的应用尝试创建一个前台服务且未请求 FOREGROUND_SERVICE,则系统会引发 SecurityException。 另外这是普通权限,因此,系统会自动为请求权限的应用授予此权限。
解决办法:
在AndroidManifest里添加权限
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
1.2 在android 8.0上会出现java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
原因:
在安卓8.0版本时为了支持全面屏,增加了一个限制:如果是透明的Activity,则不能固定它的方向。然而这个bug只有在8.0中有,8.0以上已经修复。具体crash有两种:
1.Activity的风格为透明,在manifest文件中指定了一个方向
2.Activity的风格为透明,如果调用setRequestedOrientation方法固定方向
什么是透明Activity?
看代码:
if (getApplicationInfo().targetSdkVersion > O && mActivityInfo.isFixedOrientation()) {
final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
ta.recycle();
if (isTranslucentOrFloating) {
throw new IllegalStateException(
"Only fullscreen opaque activities can request orientation");
}
}
public static boolean isTranslucentOrFloating(TypedArray attributes) {
final boolean isTranslucent =
attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent,
false);
final boolean isSwipeToDismiss = !attributes.hasValue(
com.android.internal.R.styleable.Window_windowIsTranslucent)
&& attributes.getBoolean(
com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
final boolean isFloating =
attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating,
false);
return isFloating || isTranslucent || isSwipeToDismiss;
}
大意就是,有上面三种风格就是透明。
解决办法:
需要的话透明activity不设置屏幕方向,或者参照Only fullscreen activities can request orientation终极解决方法中建议的方法
1.3 隐私政策和服务条款页面打不开(java.io.IOException: Cleartext HTTP traffic to xxxxx not permitted)
原因:
隐私政策和服务条款页面访问的是Http请求,而Android 9.0的系统上面默认所有Http的请求都被阻止了。
解决办法:
在AnroidManifest.xml中的application显示设置
<application android:usesCleartextTraffic="true">
1.4 有的Lottie动画出现java.lang.IllegalArgumentException: Invalid Layer Save Flag - only ALL_SAVE_FLAGS is allowed,该错误在Lottie github项目的issue上有(https://github.com/airbnb/lottie-android/issues/802)
解决办法:
将Lottie版本升级到2.7.0
1.5startForeground中Notification,invalid channel
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=main_service pri=-2 contentView=null vibrate=null sound=null defaults=0x0 flags=0x42 color=0x00000000 category=service vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2082)
at android.os.Handler.dispatchMessage(Handler.java:109)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:7539)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)
解决办法:使用同一个Notification,点击打开主界面
@RequiresApi(api = Build.VERSION_CODES.O)
public static Notification createMainNotification(Context context){
NotificationChannel chan = new NotificationChannel("aaa",
context.getResources().getString(R.string.app_name), NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager service = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
service.createNotificationChannel(chan);
Intent intent = new Intent(context, MessageMainContainer.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return new NotificationCompat.Builder(context, "aaa")
.setContentTitle(context.getResources().getString(R.string.app_is_running, context.getResources().getString(R.string.app_label)))
.setContentText(context.getResources().getString(R.string.tap_for_more))
.setSmallIcon(R.drawable.stat_notify_sms)
.setContentIntent(pendingIntent)
.setOngoing(true).setPriority(Notification.PRIORITY_MIN)
.setCategory(NotificationCompat.CATEGORY_SERVICE).build();
}
1.6Apache HTTP 客户端弃用
错误log:
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.http.conn.scheme.SchemeRegistry" on path: DexPathList[zip file "/data/app/messenger.sms-cBipRhyKs_7fB9PVuBzfYA==/base.apk"],nativeLibraryDirectories=[/data/app/messenger.sms-cBipRhyKs_7fB9PVuBzfYA==/lib/arm64, /data/app/messenger.sms-cBipRhyKs_7fB9PVuBzfYA==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64](/xiaoniudonghe2015/Android-Java-Code-Style/wiki/zip-file-"/data/app/messenger.sms-cBipRhyKs_7fB9PVuBzfYA==/base.apk"],nativeLibraryDirectories=[/data/app/messenger.sms-cBipRhyKs_7fB9PVuBzfYA==/lib/arm64,-/data/app/messenger.sms-cBipRhyKs_7fB9PVuBzfYA==/base.apk!/lib/arm64-v8a,-/system/lib64,-/product/lib64)
解决办法:
在 Android 6.0 中,我们取消了对 Apache HTTP 客户端的支持。 从 Android 9 开始,默认情况下该内容库已从 bootclasspath 中移除且不可用于应用。
要继续使用 Apache HTTP 客户端,以 Android 9 及更高版本为目标的应用可以向其 AndroidManifest.xml 添加以下内容:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
注:拥有最低 SDK 版本 23 或更低版本的应用需要 android:required="false" 属性,因为在 API 级别低于 24 的设备上,org.apache.http.legacy 库不可用。 (在这些设备上,Apache HTTP 类在 bootclasspath 中提供。)
作为使用运行时 Apache 库的替代,应用可以在其 APK 中绑定自己的 org.apache.http 库版本。 如果进行此操作,您必须将该库重新打包(使用一个类似 Jar Jar 的实用程序)以避免运行时中提供的类存在类兼容性问题。
Messenger/Messenger pro/Messenger2020
1.需要添加
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
2.透明Activity,设置屏幕方向的话,在8.0会crash
firebase推送升级,新闻弹窗 结果页弹窗 通话助手引导页弹窗
3.前台服务的话,没有显示Notification,现在需要显示Notification
Getinsta
1.需要添加
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
2.透明Activity,设置屏幕方向的话,在8.0会crash
提示升级弹窗
3.前台服务的话,没有显示Notification,现在需要显示Notification
Sms/Sms pro/Sms2020
1.需要添加
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
2.透明Activity,设置屏幕方向的话,在8.0会crash
结果页弹窗 通话助手引导页弹窗 备份达到上限提示弹窗