升級(jí)targetSdkVersion遇到的問題記錄

最近項(xiàng)目升級(jí)targetSdkVersion,下面記錄下升級(jí)過程中遇到的問題:

問題1、targetSdkVersion 升級(jí)到27或以上,http資源或圖片訪問不了,報(bào)錯(cuò)Cleartext HTTP traffic to xxx not permitted

原因:Google官方要求android P及上設(shè)備網(wǎng)絡(luò)請(qǐng)求強(qiáng)制使用加密的請(qǐng)求,若使用非加密的明文http請(qǐng)求,會(huì)導(dǎo)致網(wǎng)絡(luò)請(qǐng)求失敗,https請(qǐng)求不受影響。

解決方法:

方法1 、將targetSdkVersion降到27或以下
方法2、將資源或網(wǎng)絡(luò)請(qǐng)求改成https
方法 3、在AndroidManifest application標(biāo)簽下配置android:usesCleartextTraffic="true"

問題2:targetSdkVersion 升級(jí)到 29及以上,在android Q的手機(jī)訪問相冊(cè)為空白,即使是有讀寫外存的權(quán)限,依然會(huì)拋出了類似下面的FileNotFoundException異常,Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)

原因:androidQ(29)及以上默認(rèn)開啟了分區(qū)存儲(chǔ)機(jī)制。
解決方法:

1、方案一:把應(yīng)用的 targetSdkVersion設(shè)置為29以下(臨時(shí)過渡)

2、方案二:在AndroidManifest.xml的Application標(biāo)簽下設(shè)置 android:requestLegacyExternalStorage=“true”(臨時(shí)過渡)

111111.jpg

3、方案三:通過Android SAF存儲(chǔ)訪問框架來(lái)訪問

4、方案四:分區(qū)存儲(chǔ)適配(官方推薦)

問題3:androidQ 沒有判斷是否有READ_PHONE_STATE權(quán)限,直接調(diào)用((TelephonyManager) context.

getSystemService(context.TELEPHONY_SERVICE)).getDeviceId() 會(huì)崩潰,升級(jí)之前只是會(huì)返回null。

解決方案:調(diào)用之前加權(quán)限判斷或try catch處理,或根據(jù)api版本判斷是否獲取deviceID(因?yàn)閍ndroid10即使有權(quán)限也獲取不到deviceid了)。

問題4. targetSdkVersion 升級(jí)到 27及以上,在android8.0設(shè)備上,透明主題的Activity配置固定方向后報(bào)"Only fullscreen activities can request orientation",targetSdkVersion26正常。

異常分析:

Entry ent = AttributeCache.instance().get(packageName,realTheme, com.android.internal.R.styleable.Window, userId);
final boolean translucent = ent != null && (ent.array.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false)|| (!ent.array.hasValue(
                com.android.internal.R.styleable.Window_windowIsTranslucent) &&  ent.array.getBoolean(com.android.internal.R.styleable.Window_windowSwipeToDismiss,false)));
fullscreen = ent != null && !ent.array.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent;
fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
noDisplay = ent != null && ent.array.getBoolean(com.android.internal.R.styleable.Window_windowNoDisplay, false);

if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen && appInfo.targetSdkVersion > O) {
    throw new IllegalStateException("Only fullscreen activities can request orientation");
}

從以上27源碼可以看出同時(shí)滿足3個(gè)條件就會(huì)拋出異常
1、ActivityInfo.isFixedOrientation(requestedOrientation) 設(shè)置了固定方向
2、appInfo.targetSdkVersion > O appInfo.targetSdkVersion>26
3 、非全屏,包含一下三種情況均認(rèn)為非全屏
“windowIsTranslucent”為true;
“windowIsTranslucent”為false,但“windowSwipeToDismiss”為true;
“windowIsFloating“為true;

解決方案:
方案一:去除AndroidManifest中的固定方向設(shè)置
方案二:targetSdkVersion設(shè)置26
方案三:activity設(shè)置非透明
方案四:通過反射,讓系統(tǒng)繞過屏幕方向的檢測(cè),設(shè)置屏幕不固定

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            fixOrientation();
        }
}
 private boolean isTranslucentOrFloating(){
        boolean isTranslucentOrFloating = false;
        try {
            int [] styleableRes = (int[]) Class.forName("com.android.internal.R$styleable").getField("Window").get(null);
            final TypedArray ta = obtainStyledAttributes(styleableRes);
            Method m = ActivityInfo.class.getMethod("isTranslucentOrFloating", TypedArray.class);
            m.setAccessible(true);
            isTranslucentOrFloating = (boolean)m.invoke(null, ta);
            m.setAccessible(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isTranslucentOrFloating;
    }


    private boolean fixOrientation(){
        try {
            Field field = Activity.class.getDeclaredField("mActivityInfo");
            field.setAccessible(true);
            ActivityInfo o = (ActivityInfo)field.get(this);
            o.screenOrientation = -1;
            field.setAccessible(false);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容