原文地址:關於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會有提示警告,且編譯的時候會報錯(如果你不調整的話)
一般來說,按照上面改完AndroidManifest檔案就差不多了
但是,我驗證過了,使用高版本確實是能夠編譯成功,但還是會報錯
於是想到了,IM模組還有依賴其他aar(如各大手機廠商的推播SDK),裡面的清單檔案可能沒改?
於是通過左側專案管理器的依賴檢視功能,可以一個個檢視AndroidManifest檔案,於是便是發現是存在有某些有用到了<intent-filter>
標籤的,但是沒有宣告exported屬性的
這個時候有兩種解決思路:
這個就比較簡單,一般用的第三方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/'}
最終問題得以解決
當然,如果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:不過這個方法具體我還沒有嘗試過,各位可以自行嘗試下哈