设置系统时间,首先需要保证app的uid为system,关于如何设置uid,可以看看这篇 App设置系统签名
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xxx.xxx" android:sharedUserId="android.uid.system">其次需要给它相关权限
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <uses-permission android:name="android.permission.SET_TIME_ZONE" />接下来进入正题。 设置系统时间我是按照源码写的照搬来的,主要是通过Calendar进行日期的设定,通过Calendar.getTimeInMillis()获取毫秒数,再通过SystemClock.setCurrentTimeMillis()来进行设置。 源码的路径是/packages/apps/Settings/src/com/android/settings/datetime/DatePreferenceController.java,我是照搬里面的setDate()方法,感兴趣可以在xref上找找。
设置系统时间(仅设置xx:xx) public void setTime(int hour,int minute) throws IOException { calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); long when = calendar.getTimeInMillis(); if (when / MILLIS_RATIO < Integer.MAX_VALUE) { SystemClock.setCurrentTimeMillis(when); } long now = Calendar.getInstance().getTimeInMillis(); if (now - when > EXECUTE_DELAYED) { throw new IOException("failed to set Time."); } } 设置系统日期(仅设置到xxxx年xx月xx日) public void setDate(int year, int month, int day) throws IOException { calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month); calendar.set(Calendar.DAY_OF_MONTH, day); long when = calendar.getTimeInMillis(); if (when / MILLIS_RATIO < Integer.MAX_VALUE) { SystemClock.setCurrentTimeMillis(when); } long now = Calendar.getInstance().getTimeInMillis(); if (now - when > EXECUTE_DELAYED) { throw new IOException("failed to set Date."); } } 设置系统是否自动获取时间 /** * @param context Activity's context. * @param checked If checked > 0, it will auto set date. */ public void setAutoDateTime(Context context, int checked) { android.provider.Settings.Global.putInt(context.getContentResolver(), android.provider.Settings.Global.AUTO_TIME, checked); } 判断系统是否自动获取时间 /** * @param context Activity's context. * @return If date is auto setting. */ public boolean checkDateAutoSet(Context context) { boolean isAutoSet; try { isAutoSet = android.provider.Settings.Global.getInt(context.getContentResolver(), android.provider.Settings.Global.AUTO_TIME) > 0; } catch (Settings.SettingNotFoundException exception) { exception.printStackTrace(); isAutoSet = false; } return isAutoSet; }网上找的所有的设置系统时区都是使用Calendar的构造,将TimeZone传进去,经过测试,完全不管用。 我去源码找了一下,发现系统是通过AlarmManager来修改TimeZone的。 关于第一种方法无法修改,应该是没有修改系统的preference,因此无用。(其实第一种方法只是修改Calendar的时间,是否修改了系统时钟未知) 贴一下按源码写的方法。
设置系统时区 public void setTimeZone(Context context,String timeZone) { final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager.setTimeZone(timeZone); } 设置系统是否自动获取时区 /** * @param context Activity's context. * @param checked If checked > 0, it will auto set timezone. */ public void setAutoTimeZone(Context context, int checked) { android.provider.Settings.Global.putInt(context.getContentResolver(), android.provider.Settings.Global.AUTO_TIME_ZONE, checked); } 判断系统是否自动获取时区 关于判断系统是否自动获取时区,与上文中的判断是否自动获取时间类似,将AUTO_TIME改成AUTO_TIME_ZONE即可。参考的网上几篇,发现重启设备后,语言设置会清掉。 之后去源码翻了翻,发现了与网上代码的主要区别;更新configuration时,系统使用的是updatePersistentConfiguration,网上所有给出的方案都是updateConfiguration,并没有将设定持久化保存。 改成updatePersistentConfiguration后,测试,管用! android 设置语言的主要实现代码:/frameworks/base/core/java/com/android/internal/app/LocalePicker.java 设置系统语言需要通过反射来改变。注释内容表示下方代码对应源码中的语句。
public void changeSystemLanguage(Locale locale) { if (locale != null) { try { //final IActivityManager am = ActivityManagerNative.getDefault(); Class classActivityManagerNative = Class.forName("android.app.ActivityManagerNative"); Method getDefault = classActivityManagerNative.getDeclaredMethod("getDefault"); Object objIActivityManager = getDefault.invoke(classActivityManagerNative); //final Configuration config = am.getConfiguration(); Class classIActivityManager = Class.forName("android.app.IActivityManager"); Method getConfiguration = classIActivityManager.getDeclaredMethod("getConfiguration"); Configuration config = (Configuration) getConfiguration.invoke(objIActivityManager); //config.setLocales(locales); config.setLocales(new LocaleList(locale)); //config.userSetLocale = true; Class clzConfig = Class .forName("android.content.res.Configuration"); java.lang.reflect.Field userSetLocale = clzConfig .getField("userSetLocale"); userSetLocale.set(config, true); //am.updatePersistentConfiguration(config); Class[] clzParams = {Configuration.class}; Method updatePersistentConfiguration = classIActivityManager.getDeclaredMethod("updatePersistentConfiguration", clzParams); updatePersistentConfiguration.invoke(objIActivityManager, config); BackupManager.dataChanged("com.android.providers.settings"); } catch (Exception exception) { exception.printStackTrace(); } } }参考 android源码中设置语言的代码相关位置 Android实践 – 设置系统日期时间和时区