4

关于Android12安装apk出现-108异常INSTALL_PARSE_FAILED_MANIFEST_MALFORMED的解决方...

 1 year ago
source link: https://www.cnblogs.com/stars-one/p/16915222.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

关于Android12安装apk出现-108异常INSTALL_PARSE_FAILED_MANIFEST_MALFORMED的解决方法

本文为作者原创,允许转载,不过请在文章开头明显处注明链接和出处!!! 谢谢配合~
作者:stars-one
链接:https://www.cnblogs.com/stars-one/p/16915222.html

本篇大约有3257个字,阅读预计需要4.07分钟


原文地址:关于Android12安装apk出现-108异常INSTALL_PARSE_FAILED_MANIFEST_MALFORMED的解决方法 - Stars-One的杂货小窝

用户的小米手机上出现以下界面问题

1210268-20221122140314754-480187079.png

小米手机为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),里面的清单文件可能没改?

1210268-20221122145350942-1142669522.png

于是通过左侧项目管理器的依赖查看功能,可以一个个查看AndroidManifest文件,于是便是发现是存在有某些有用到了<intent-filter>标签的,但是没有声明exported属性的

1210268-20221122145433269-845181623.png

这个时候有两种解决思路:

  • 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:不过这个方法具体我还没有尝试过,各位可以自行尝试下哈


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK