關於Android12安裝apk出現-108異常INSTALL_PARSE_FAILED_MANIFEST_MALFORMED的解決方法

2022-11-22 18:02:08

原文地址:關於Android12安裝apk出現-108異常INSTALL_PARSE_FAILED_MANIFEST_MALFORMED的解決方法 - Stars-One的雜貨小窩

問題描述

使用者的小米手機上出現以下介面問題

小米手機為Android12系統,根據安裝錯誤碼得知,這個是由於AndroidManifest資源結構存在錯誤導致的

解決方法

解決方法其實在之前一文關於Android安裝apk出現解析包異常問題情況總結 - Stars-one - 部落格園也已經提到過了,這次來此詳細的說明

如果您的應用以 Android 12 或更高版本為目標平臺,且包含使用 intent 過濾器的 activity、服務或廣播接收器,您必須為這些應用元件顯式宣告 android:exported 屬性。

警告:如果 activity、服務或廣播接收器使用 intent 過濾器,並且未顯式宣告 android:exported 的值,您的應用將無法在搭載 Android 12 或更高版本的裝置上進行安裝。
如果應用元件包含 LAUNCHER 類別,請將 android:exported 設定為 true。在大多數其他情況下,請將 android:exported 設定為 false。

翻譯成通俗的語言就是說,當你的AndroidManifest.xml中檔案中,如果存在Activity,Receiver,Service使用到了<intent-filter>標籤,則是要顯示宣告android:exported的值

大部分常規設定為android:exported="false"即可,如下面一個簡單的例子:

<service android:name="com.example.app.backgroundService"
         android:exported="false">
    <intent-filter>
        <action android:name="com.example.app.START_BACKGROUND" />
    </intent-filter>
</service>

如果包含啟動(LAUNCHER)類別,則宣告為true(實際上說的是App首次啟動開啟的那個Activity),如下面程式碼:

<activity android:name=".MainActivity" android:exported="true" android:theme="@style/MySplashTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

如果自己去一個個排查就比較麻煩,可以用Android Studio去輔助調整,在Android Studio 2020.3.1 Canary 11 或更高版本會有對應的Lint提示,開啟AndroidManifest.xml會有提示警告,且編譯的時候會報錯(如果你不調整的話)

進一步排查三方aar

一般來說,按照上面改完AndroidManifest檔案就差不多了

但是,我驗證過了,使用高版本確實是能夠編譯成功,但還是會報錯

於是想到了,IM模組還有依賴其他aar(如各大手機廠商的推播SDK),裡面的清單檔案可能沒改?

於是通過左側專案管理器的依賴檢視功能,可以一個個檢視AndroidManifest檔案,於是便是發現是存在有某些有用到了<intent-filter>標籤的,但是沒有宣告exported屬性的

這個時候有兩種解決思路:

  • 1.升級第三方SDK版本
  • 2.使用Manifest的合併功能

1.升級第三方SDK版本

這個就比較簡單,一般用的第三方SDK都會積極更新,我們去拿到最新的版本,然後重新依賴即可

這裡,我是直接參考了騰訊IM最新的demo程式碼,對版本進行了升級

// 主包
implementation 'com.tencent.tpns:tpns:1.3.1.1-release'
// 小米
implementation "com.tencent.tpns:xiaomi:1.3.1.1-release"
// 魅族
implementation "com.tencent.tpns:meizu:1.3.1.1-release"
// OPPO
implementation "com.tencent.tpns:oppo:1.3.1.1-release"
// vivo
implementation "com.tencent.tpns:vivo:1.3.2.0-release"
// 華為
implementation 'com.tencent.tpns:huawei:1.3.1.1-release'

然後發現,騰訊IM的demo並沒有升級華為推播,華為推播SDK裡面還有存在對應沒有宣告exported的元件,於是就去華為推播官網找了個新版本下載,就成功解決問題了

implementation 'com.huawei.hms:push:6.7.0.300'

當然,這裡還需要新增一下華為的maven倉庫源

maven {url 'https://developer.huawei.com/repo/'}

最終問題得以解決

2.合併功能

當然,如果SDK提供方不積極更新,且更新後也沒有注意去適配Android12,那麼這個時候我們只好自力更生了,可以用Android特有的清單檔案合併功能來變相地修改SDK裡的AndroidManifest的設定

Android清單檔案,最終會將多個Module的AndroidManifest合併成一個,如果有衝突的,需要我們設定對應的衝突策略,如replace替換或ignore忽略

我們可以在app模組下的AndroidMainfest.xml,將SDK對應的那個元件宣告標籤複製出來,然後手動去加上exported屬性,並加上replace的合併替換策略,如下程式碼所示

<receiver tools:replace="android:exported" android:exported="false" android:name="com.tencent.qcloud.tim.demo.thirdpush.TPNSPush.TPNSMessageReceiver">
    <intent-filter>
        <!-- 接收訊息透傳 -->
        <action android:name="com.tencent.android.xg.vip.action.PUSH_MESSAGE" />
        <!-- 監聽註冊、反註冊、設定/刪除標籤、通知被點選等處理結果 -->
        <action android:name="com.tencent.android.xg.vip.action.FEEDBACK" />
    </intent-filter>
</receiver>

PS:不過這個方法具體我還沒有嘗試過,各位可以自行嘗試下哈

參考