旧版 Android 系统为目标平台的应用的警告

1.问题呈现:

在Android10.0中运行应用会提示“此应用专为旧版Android打造,可能无法正常运行,请尝试更新或与开发者联系”。

具体截图如下:
旧版 Android 系统为目标平台的应用的警告_第1张图片

为什么在Android10.0会出现这个提示,而在低版本中却没有呐?

2.问题分析

我们可以在官方网站中的Android10.0版本中的影响应用的行为变更中找到答案。

旧版 Android 系统为目标平台的应用的警告_第2张图片

可以看出是项目中配置targetSdkVersion的影响。那么什么是targetSdkVersion。

3.targetSdkVersion介绍

一个用于指定应用的目标 API 级别的整数。如果未设置,其默认值与为 minSdkVersion 指定的值相等。

该属性用于通知系统,您已针对目标版本进行测试,并且系统不应通过启用任何兼容性行为,以保持您的应用与目标版本的向前兼容性。应用仍可在较低版本上运行(最低版本为 minSdkVersion)。

Android 会随新版本的推出而逐渐发展,在此过程中,某些行为乃至外观可能会发生变化。不过,如果平台的 API 级别高于应用 targetSdkVersion 所声明的版本,系统便可通过启用兼容性行为,确保应用继续以您所期望的方式工作。您可以将 targetSdkVersion 指定为符合应用所运行平台的 API 级别,从而停用此类兼容性行为。例如,如果将该值设置为“11”或更高,系统便可在应用运行在 Android 3.0 或更高版本的平台上时对其应用新的默认主题 (Holo),还可在应用运行在更大屏幕上时停用屏幕兼容性模式(因为对 API 级别 11 的支持隐含了对更大屏幕的支持)。

系统可根据您为该属性设置的值启用许多兼容性行为。Build.VERSION_CODES 参考资料中的相应平台版本介绍了其中几种行为。

如要让应用与各 Android 版本保持同步,您应增加该属性的值,使其与最新 API 级别一致,然后在相应平台版本上对应用进行全面测试。

4.源码分析

AppWarnings.java,在onStartActivity会检测targetSdkVersion,如果小于系统的支持最小的目标版本,则弹出提示框。代码块如下:

/**
 * Shows the "deprecated target sdk" warning, if necessary.
 *
 * @param r activity record for which the warning may be displayed
 */
public void showDeprecatedTargetDialogIfNeeded(ActivityRecord r) {
    if (r.appInfo.targetSdkVersion < Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT) {
        mUiHandler.showDeprecatedTargetDialog(r);
    }
}

那么 Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT 在Android10.0的时候是等于多少呐?继续跟源码

/**
 * The current lowest supported value of app target SDK. Applications targeting
 * lower values may not function on devices running this SDK version. Its possible
 * values are defined in {@link Build.VERSION_CODES}.
 *
 * @hide
 */
public static final int MIN_SUPPORTED_TARGET_SDK_INT = SystemProperties.getInt(
        "ro.build.version.min_supported_target_sdk", 0);

这是个隐藏属性,android9.0开始限制@hide方法的使用,即使是用反射也无法使用hide方法。

5.获取Android10.0中支持的最小目标版本

获取的代码块如下:

public static String getSystemProperty(String propName) {
    String line;
    BufferedReader input = null;
    try {
        Process p = Runtime.getRuntime().exec("getprop " + propName);
        input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
        line = input.readLine();
        input.close();
    } catch (IOException ex) {
        Log.d(TAG, "Unable to read sysprop " + propName, ex);
        return null;
    } finally {
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                Log.d(TAG, "Exception while closing InputStream", e);
            }
        }
    }
    return line;
}

使用方法:

String targetValue = getSystemProperty("ro.build.version.min_supported_target_sdk");

6.总结

在Android10.0获取到的是23,那么设置项目中targetSdkVersion大于等于23就可以了。但是需要添加动态权限申请。在此有个取巧的方法,targetSdkVersion低的在高版本运行时,系统会默认弹出权限申请框,我们可以根据这个弹框,在项目入口动态的申请这些权限。

特别注意:targetSdkVersion设置需谨慎,一旦发布了targetSdkVersion高的,再发布低targetSdkVersion的,应用无法实现覆盖安装。安装失败后提示应用未安装(三星s8手机)。

 

 

 

你可能感兴趣的:(android,Java,android,java)