3

To get device ID I usually use following snippet:

String android_id = Settings.System.getString(getContentResolver(), Secure.ANDROID_ID);

Today when I looked up the logcat in Android Studio it says

"....Setting android_id has moved from android.provider.Settings.System to android.provider.Settings.Secure, returning read-only value."

So I changed my code to:

String android_id = Settings.Secure.getString(getContentResolver(), Secure.ANDROID_ID);

As you can see, the System just got replaced with Secure, nothing else is changed. I wonder what's the difference / reason they moved the namespace, lying behind this change. Just out of curiosity.

BTW, to clearify further, my app uses API16 (4.1.2)

Ge Rong
  • 416
  • 5
  • 17

1 Answers1

12

tl;dr answer: In essence, Settings.System.getString above is calling Settings.Secure.getstring.

As always, the Android source code has the answer.

Here's the getString method for Settings.System (Android 4.1.2):

public synchronized static String getString(ContentResolver resolver, String name) {
             if (MOVED_TO_SECURE.contains(name)) {
                 Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System"
                         + " to android.provider.Settings.Secure, returning read-only value.");
                 return Secure.getString(resolver, name);
             }
             if (sNameValueCache == null) {
                 sNameValueCache = new NameValueCache(SYS_PROP_SETTING_VERSION, CONTENT_URI,
                                                      CALL_METHOD_GET_SYSTEM);
             }
             return sNameValueCache.getString(resolver, name);
         }

And the below is for Settings.Secure (Android 4.1.2)

public synchronized static String getString(ContentResolver resolver, String name) {
            if (sNameValueCache == null) {
                sNameValueCache = new NameValueCache(SYS_PROP_SETTING_VERSION, CONTENT_URI,
                                                     CALL_METHOD_GET_SECURE);
            }

            if (sLockSettings == null) {
                sLockSettings = ILockSettings.Stub.asInterface(
                        (IBinder) ServiceManager.getService("lock_settings"));
                sIsSystemProcess = Process.myUid() == Process.SYSTEM_UID;
            }
            if (sLockSettings != null && !sIsSystemProcess
                    && MOVED_TO_LOCK_SETTINGS.contains(name)) {
                try {
                    return sLockSettings.getString(name, "0", UserId.getCallingUserId());
                } catch (RemoteException re) {
                    // Fall through
                }
            }

            return sNameValueCache.getString(resolver, name);
        }

When you call Settings.System.getString, you will see that it checks if MOVED_TO_SECURE, which is a hash table, contains the name (ANDROID_ID) the method calls Secure.getString instead Here's the entire MOVED_TO_SECURE hashtable:

private static final HashSet<String> MOVED_TO_SECURE;
        static {
            MOVED_TO_SECURE = new HashSet<String>(30);
            MOVED_TO_SECURE.add(Secure.ANDROID_ID);
            MOVED_TO_SECURE.add(Secure.HTTP_PROXY);
            MOVED_TO_SECURE.add(Secure.LOCATION_PROVIDERS_ALLOWED);
            MOVED_TO_SECURE.add(Secure.LOCK_BIOMETRIC_WEAK_FLAGS);
            MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_ENABLED);
            MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_VISIBLE);
            MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED);
            MOVED_TO_SECURE.add(Secure.LOGGING_ID);
            MOVED_TO_SECURE.add(Secure.PARENTAL_CONTROL_ENABLED);
            MOVED_TO_SECURE.add(Secure.PARENTAL_CONTROL_LAST_UPDATE);
            MOVED_TO_SECURE.add(Secure.PARENTAL_CONTROL_REDIRECT_URL);
            MOVED_TO_SECURE.add(Secure.SETTINGS_CLASSNAME);
            MOVED_TO_SECURE.add(Secure.USE_GOOGLE_MAIL);
            MOVED_TO_SECURE.add(Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
            MOVED_TO_SECURE.add(Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY);
            MOVED_TO_SECURE.add(Secure.WIFI_NUM_OPEN_NETWORKS_KEPT);
            MOVED_TO_SECURE.add(Secure.WIFI_ON);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_AP_COUNT);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_MAX_AP_CHECKS);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_ON);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_PING_COUNT);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_PING_DELAY_MS);
            MOVED_TO_SECURE.add(Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS);

            // At one time in System, then Global, but now back in Secure
            MOVED_TO_SECURE.add(Secure.INSTALL_NON_MARKET_APPS);
        }

The reason for this is that as Google updates Android framework, they reorganize the configuration identifiers to different locations mostly due to security concerns. Usually, this happens because Google internally decides that some of the available configurations should not be modified by the app. (Unless if you can somehow acquire WRITE_SECURE_SETTINGS permission, which is not available on typical applications ). And they wouldn't want to break compatibility on old versions, so they silently call the appropriate getString instead of raising an exception.

The most notable change occurs past 4.2, where they added Settings.Global and moved a whole lot of configuration identifiers there. If you need to read system configuration on the device level past 4.2, it is recommended that you use Settings.Global instead.

Source Code: http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/android/4.1.1.4/android/provider/Settings.java

Community
  • 1
  • 1
TtT23
  • 6,876
  • 34
  • 103
  • 174