ionic應用兼容Android9與10的經歷

水平有限,若是存在問題歡迎你們訪問個人博客批評指正.java

ionic應用兼容android9的經歷

文中Android P就是Android 9,這一塊緣由你們本身google.android

忽然,給用戶開發的App沒法在Android9與Android10上正常使用,甚至10上面沒法進行安裝,不得不拉取很早以前的代碼進行問題排查.apache

此前是ionic4與Angular的混合開發項目,因此我首先想到的事Android9以上api進行了變更,若是是權限好處理,若是是api而且涉及到第三方cordova插件那麼就有點麻煩,不能等到插件做者本身更新的狀況下咱們只能本身基於源碼去修改.就像我以前想找一個支持中文TTS的cordova插件,網上能找到的幾乎所有是英文的.最後只能本身封裝(中文TTS插件),因此若是瞭解cordova插件原理及懂一些java知識,第二點也不麻煩.api

好在咱們此次的問題出在本身自己身上,就是那種好解決的,咱們如今咱們添加的android平臺源碼裏面改動.網絡

問題解決

Apache HTTP client 類丟失

將 compileSdkVersion 升級到 28(Android9) 以後,若是在項目中用到了 Apache HTTP client 的相關類,就會拋出找不到這些類的錯誤。這是由於官方已經啓動類加載器中將其移除,若是仍然須要使用 Apache HTTP client,能夠在AndroidManifest.xml文件中加入:session

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

具體再application節點下.架構

網絡沒法鏈接

CLEARTEXT communication to life.115.com not permitted by network security policyapp

緣由: Android P之後 限制了明文流量的網絡請求,非加密的流量請求都會被系統禁止掉dom

方案一

既然不讓用明文,那咱們將http換成https就能夠解決問題了,這也是之後的趨勢,大勢所趨.ionic

方案二

考慮到有些請求是和客戶打交道,太麻煩,那麼還有其餘解決辦法.

在資源文件新建xml目錄(res下創建xml目錄,通常本身存在),新建一個文件network_security_config.xml(通常也存在),添加或修改原有內容:

所有放開

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

或者容許部分:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!--<base-config cleartextTrafficPermitted="true" />-->
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">sample.domain.com</domain>
    </domain-config>
</network-security-config>

而後在AndroidManifest.xml的application節點屬性上添加:

<application
    ...
    android:networkSecurityConfig="@xml/network_security_config">

其它方案:

  1. 不要使用過高的targetversion,26以及之前的版本仍是能夠正常訪問http.
  2. 在AndroidMainifest的加入android:usesCleartextTraffic
<application
    android:usesCleartextTraffic="true"/>

Android 9使用前臺服務報異常

緣由:在安卓P版本以後,必需要授予FOREGROUND_SERVICE權限,纔可以使用前臺服務,不然會拋出異常。

那就在AndroidManifest.xml中manifest添加權限唄:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

到這一步,我在Android P的問題其實已經解決了,Android 10的一會再說,可是我仍是把我解決過程當中網上你們提的其餘問題列舉一下.

劉海屏適配(原生代碼)

好比咱們須要全屏顯示的時候,Google在api28中已經作了處理。以下面代碼:

requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    //android p 劉海屏適配
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//加版本判斷,28如下會報錯
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.layoutInDisplayCutoutMode
                = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        getWindow().setAttributes(lp);
    }

layoutInDisplayCutoutMode值說明:

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT:默認狀況下,全屏窗口不會使用到挖孔區域,非全屏窗口可正常使用挖孔區域。
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS:窗口聲明使用挖孔區域
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES:窗口聲明使用挖孔區域
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER:窗口聲明不使用挖孔區域

限制靜態廣播的接收

升級安卓P以後,隱式廣播將會被全面禁止,在AndroidManifest中註冊的Receiver將不可以生效,若是你的清單文件中有以下的監聽器:

<receiver android:name="com.yanghaoyi.receiver.UpdateReceiver">
        <intent-filter>
            <action android:name="com.yanghaoyi.action.ACTION_UPDATE" />
        </intent-filter>
</receiver>

你須要移除上面的代碼,並在應用中進行動態註冊,例如:

private void registerReceiver(){
    myReceiver = new MyReceiver();
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(TOAST_ACTION);
    registerReceiver(myReceiver, intentFilter);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(myReceiver);
}

非全屏透明Activity禁用設置orientation

java.lang.IllegalStateException: Only fullscreen activities can request orientation

非全屏透明頁面不容許設置方向,不然會拋異常.

若是一個Activity的Style符合下面三個條件之一,認爲不是「fullscreen」:

「windowIsTranslucent」爲true;

「windowIsTranslucent」爲false,但「windowSwipeToDismiss」爲true;

「windowIsFloating「爲true;

解決方案:android:windowIsTranslucent設置爲false。

ionic兼容優化

上面我採用了添加xml打開明文訪問,前臺權限以及Apache HTTP client 類丟失解決方案,每次添加完平臺都得改一次代碼,是否是至關不方便,那麼ionic自己的config.xml就派上用場了.

將上文提到的network_security_config.xml文件放在resources/android/xml目錄下.

而且在config.xml的widget標籤上添加屬性:

<widget ... xmlns:android="http://schemas.android.com/apk/res/android">
...
</widget>

在config.xml的android平臺配置裏面添加:

<platform name="android">
        <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
            <application android:networkSecurityConfig="@xml/network_security_config" />
        </edit-config>
        <config-file parent="/manifest" target="app/src/main/AndroidManifest.xml">
            <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
        </config-file>
        <config-file parent="/manifest/application" target="app/src/main/AndroidManifest.xml">
            <uses-library android:name="org.apache.http.legacy" android:required="false" />
        </config-file>
 </platform>

而後就不用擔憂每次刪除平臺後再次添加劇新修改代碼了.

Android 10的一些問題

在Android 10的一些手機上,好比華爲,不知道是由於手機本身設置的緣由仍是android升級了,不容許安裝非正式版app,因此咱們在發送測試版(debug)版本的apk安裝會失敗,由於有時候並非咱們都是整個開發完上應用市場的,客戶可能須要提早體驗或者看效果.而每一個手機關閉設置又不同,反正華爲的沒找見,那麼咱們發佈時應該將咱們的app進行正式簽名,防止客戶安裝失敗.

並且簽名也是咱們app正式發佈的必須流程.

具體簽名流程請參考個人Android簽名一文.

INSTALL_FAILED_NO_MATCHING_ABIS(虛擬機的問題)

有時候咱們使用虛擬機測試應用是可能由於架構的問題,報錯:
`Installation failed with message Failed to finalize session : INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113.
It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing.`

解決方案:
在Android studio 的build.gradle文件裏(model:app):在android中添加如下內容:

android{
    ...
    splits {
        abi {
            enable true
            reset()
            include 'x86', 'armeabi-v7a','x86_64'
            universalApk true
        }
    }
}
相關文章
相關標籤/搜索