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

结果页弹窗 通话助手引导页弹窗 备份达到上限提示弹窗

3.Apache HTTP 客户端弃用

4.HTTP请求失败

5.前台服务的话,没有显示Notification,现在需要显示Notification