Android: getting an APKs minSdkVersion from Android code [duplicate]

你离开我真会死。 提交于 2019-12-07 04:01:17

问题


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)


回答1:


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.



来源:https://stackoverflow.com/questions/30455858/android-getting-an-apks-minsdkversion-from-android-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!