3

I need to check if the option "Install apps from unknown sources" is enabled or disabled. However, INSTALL_NON_MARKET_APPS was deprecated in API 17. Is there a new alternative to check this? This is the old way of checking:

boolean canInstallFromOtherSources = Settings.Secure.getInt(Settings.Secure.INSTALL_NON_MARKET_APPS) == 1;

Edit:

    boolean unknownSource = false;
    if (Build.VERSION.SDK_INT < 17) {
        unknownSource = Settings.Secure.getInt(null, Settings.Secure.INSTALL_NON_MARKET_APPS, 0) == 1;
    } else {
        unknownSource = Settings.Global.getInt(null, Settings.Global.INSTALL_NON_MARKET_APPS, 0) == 1;
    }
4

2 回答 2

7

正如文件Settings.Secure.INSTALL_NON_MARKET_APPS指出的那样,替换是Settings.Global.INSTALL_NON_MARKET_APPS.

于 2013-07-21T18:34:46.413 回答
2

Settings.Secure.INSTALL_NON_MARKET_APPS在 API 17 中已被弃用,因此如果您将 minimumSDK 设置为低于 17,则无法直接访问它并且必须使用反射。

我的解决方案:

public class BackwardCompatibility {    
    private static Class<?> settingsGlobal;

    /**
     * Returns Settings.Global class for reflective calls.
     * Global is a nested class of the Settings, has to be done in a special way.
     * 
     * @return
     */
    public static Class<?> getSettingsGlobal(){
        if (settingsGlobal!=null){
            return settingsGlobal;
        }

        try {
            Class<?> master = Class.forName("android.provider.Settings");
            Class<?>[] classes = master.getClasses();
            for(Class<?> cls : classes){
                if (cls==null) {
                    continue;
                }

                if ("android.provider.Settings$Global".equals(cls.getName())){
                    settingsGlobal = cls;
                    return settingsGlobal;
                }
            }

            return null;
        } catch(Exception ex){
            Log.e(TAG, "Reflective call not successfull", ex);
        }

        return null;
    }

    /**
     * Determines whether installing Android apks from unknown sources is allowed.
     * 
     * @param ctxt
     * @return
     */
    public static boolean isUnknownSourceInstallAllowed(Context ctxt){
        try {
            boolean unknownSource = false;
            if (Build.VERSION.SDK_INT < 17) {
                unknownSource = Settings.Secure.getInt(ctxt.getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 0) == 1;
            } else {
                // Has to use reflection since API 17 is not directly reachable.
                // Original call would be:
                //   unknownSource = Settings.Global.getInt(ctxt.getContentResolver(), Settings.Global.INSTALL_NON_MARKET_APPS, 0) == 1;
                //
                Class<?> c = getSettingsGlobal();
                Method m   = c.getMethod("getInt", new Class[] { ContentResolver.class, String.class, int.class });

                // Obtain constant value
                Field f = c.getField("INSTALL_NON_MARKET_APPS");
                final String constVal = (String) f.get(null);

                unknownSource = Integer.valueOf(1).equals((Integer) m.invoke(null, ctxt.getContentResolver(), constVal, 0));
            }

            return unknownSource;
        } catch(Exception e){
            // Handle this as you like.
            Log.w(TAG, "Cannot determine if installing from unknown sources is allowed", e);
        }

        return false;
    }
}
于 2014-03-22T18:07:32.337 回答