要获取设备ID,我通常使用以下代码段:
String android_id = Settings.System.getString(getContentResolver(), Secure.ANDROID_ID);
今天,当我在Android Studio中查找logcat时,它说
"....设置android_id已从android.provider.Settings.System移至android.provider.Settings.Secure,返回只读值."
所以我将我的代码更改为:
String android_id = Settings.Secure.getString(getContentResolver(), Secure.ANDROID_ID);
正如你所看到的,System刚刚被替换Secure,没有别的东西被改变.我想知道他们移动命名空间的区别/原因是什么,这背后是这个变化.只是出于好奇.
顺便说一句,为了进一步澄清,我的应用程序使用API16(4.1.2)
l46*_*kok 12
tl;博士回答:实质上,上面的Settings.System.getString是调用Settings.Secure.getstring.
与往常一样,Android源代码有答案.
这是Settings.System(Android 4.1.2)的getString方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
以下是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);
}
Run Code Online (Sandbox Code Playgroud)
当您调用Settings.System.getString时,您将看到它检查MOVED_TO_SECURE(这是一个哈希表)是否包含该方法调用Secure.getString的名称(ANDROID_ID)这里是整个MOVED_TO_SECURE哈希表:
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);
}
Run Code Online (Sandbox Code Playgroud)
这样做的原因是,当Google更新Android框架时,他们会将配置标识符重新组织到不同的位置,主要是出于安全考虑.通常,这是因为Google内部决定应用程序不应修改某些可用配置.(除非您能以某种方式获得WRITE_SECURE_SETTINGS权限,这在典型应用程序中不可用).并且他们不希望破坏旧版本的兼容性,因此他们默默地调用适当的getString而不是引发异常.
最值得注意的变化发生在4.2之后,他们在那里添加了Settings.Global并在那里移动了大量的配置标识符.如果您需要在4.2级以上的设备级别读取系统配置,建议您改用Settings.Global.
源代码:http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/android/4.1.1.4/android/provider/Settings.java