安卓:从安卓代码中获取APK的minSdkV版本[英] Android: getting an APKs minSdkVersion from Android code

本文是小编为大家收集整理的关于安卓:从安卓代码中获取APK的minSdkV版本的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在开发一个Android应用程序,如果用户需要它,那么能够安装其他应用程序(作为应用程序的插件).

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

现在,具有以下方法:

public PackageManager getPackageArchiveInfo(String archiveFilePath, int flags)

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

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

推荐答案

你可以做到.

对于Android n及以上,使用 官方API

对于早期版本,您可以使用 这个代码 ,这是非常有效和快速的.这是它的一点版本(即使getAttributeName返回空字符串):

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 .如果你想要它的基础知识,请考虑APKParser改进我建议 在这里

本文地址:https://www.itbaoku.cn/post/1937941.html

问题描述

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.

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.

Now, with the following method:

public PackageManager getPackageArchiveInfo(String archiveFilePath, int flags)

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.

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)

推荐答案

You can do it.

For Android N and above, use the official API.

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;
}

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.