本文介绍了Android:从 Android 代码获取 APKs minSdkVersion的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款 Android 应用,如果用户需要,它可以安装其他应用(充当我应用的插件).

I'm developing an Android app that has the ability of installing additional apps (which act as plugins for my app) if the user requires it.

但是,这些附加应用中的每一个都可能需要特定的 Android 版本才能运行.我想在运行时执行检查,看看我尝试安装的 APK 是否真的与设备兼容.

However, each of these additional apps may require a specific Android version to run. I would like to perform a check at runtime to see if the APK I'm trying to install is actually compatible with the device.

现在,使用以下方法:

public PackageManager getPackageArchiveInfo(String archiveFilePath, int flags)

我可以获取有关 APK 文件的信息.但是,问题是返回的信息似乎只包含APK的targetSdkVersion,而不包含minSdkVersion,据我了解,它实际上决定了Android的最低版本可以安装/运行应用程序.targetSdkVersion 如果我理解正确的话,它只是最佳"版本.

I can get info on an APK file. However, the problem is that the returned information seems to only include the APK's targetSdkVersion but not the minSdkVersion, which to my understanding is the one that actually determines the minimum version of Android an app can be installed/run on. The targetSdkVersion if I understand correctly is just the "optimal" version.

那么,长话短说,我如何从 Android 本身确定 APK cna 是否在设备上运行?(我知道我可以在桌面上使用 AAPT,但在 Android 本身上不可用)

So, long story short, how can I determine whether an APK cna run on the device from Android itself? (I know I can use AAPT on desktop, but that is not available on Android itself)

推荐答案

你可以做到.

对于 Android N 及更高版本,请使用 官方 API.

For Android N and above, use the official API.

对于早期版本,可以使用这段代码,非常高效快速.这是它的一个更好的版本(即使 getAttributeName 返回空字符串也能工作):

For earlier versions, you can use this code, which is very efficient and fast. Here's a bit better version of it (works even if getAttributeName returns an empty string) :

public static int getMinSdkVersion(File apkFile) throws ClassNotFoundException, IllegalAccessException, InstantiationException,
        NoSuchMethodException, InvocationTargetException, IOException, XmlPullParserException {
    final Class assetManagerClass = Class.forName("android.content.res.AssetManager");
    final AssetManager assetManager = (AssetManager) assetManagerClass.newInstance();
    final Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
    final int cookie = (Integer) addAssetPath.invoke(assetManager, apkFile.getAbsolutePath());
    final XmlResourceParser parser = assetManager.openXmlResourceParser(cookie, "AndroidManifest.xml");
    while (parser.next() != XmlPullParser.END_DOCUMENT)
        if (parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("uses-sdk"))
            for (int i = 0; i < parser.getAttributeCount(); ++i)
                if (parser.getAttributeNameResource(i) == android.R.attr.minSdkVersion)//alternative, which works most of the times: "minSdkVersion".equals(parser.getAttributeName(i)))
                    return parser.getAttributeIntValue(i, -1);
    return -1;
}

而且,如果您想要一个全面的解决方案(遗憾的是这会占用大量堆内存和时间),您可以使用 APK 解析库,例如 APKParser.如果您只想要它的基础知识,请考虑我在 此处.

And, if you want an all around solution (which sadly can take a lot of heap memory and time), you can use an APK parsing library, such as APKParser. If you want just the basics of it, consider the APKParser improvement I suggested here.

这篇关于Android:从 Android 代码获取 APKs minSdkVersion的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 20:50