Android App设置系统时间,语言和时区

tech2025-09-22  22

设置系统时间

设置系统时间,首先需要保证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即可。

获取系统时间和时区信息

获取系统时间 通过Calendar获取即可,这里只列出获取当前的小时 public int getHourOfDay() { return calendar.get(Calendar.HOUR_OF_DAY); } 获取当前是多少日 public int getDay() { return calendar.get(Calendar.DAY_OF_MONTH); } 获取当前月有多少天 项目要求通过三个PickerView来完成对日期的设定。 在修改月份的PickerView时,当月的天数必须随着月份的设定而改变。 该方法就是为此而完成的。 可以发现,填入的参数与上面的方法是一样的,但是调用方法不一样,getActualMaximum()是获取最大天数,getActualMinimum()则是获取最小天数。 /** * Get how many days in the month. * * @return days in the month. */ public int getDayOfMonth() { return calendar.getActualMaximum(Calendar.DAY_OF_MONTH); } 获取系统当前时区 TimeZone.SHORT指输出形式,SHORT输出为 GMT+09:00,LONG输出为Tokyo Standard Time Locale.US是指按何种语言输出该TimeZone信息。 关于获取TimeZone的信息,可以看看其源码里写的几个get方法。 public String getTimeZone() { return TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT, Locale.US); } 获取当前时区设定城市 项目要求显示时区和其城市信息,就用split把它分出来了。 /** * @return TimeZone's city name. */ public String getTimeZoneCity() { String[] timezone = TimeZone.getDefault().getID().split("/"); String city = timezone[1]; return city; }

设置系统语言

参考的网上几篇,发现重启设备后,语言设置会清掉。 之后去源码翻了翻,发现了与网上代码的主要区别;更新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(); } } }

获取系统语言偏好

public String getSystemLanguage(){ Locale locale = this.getResources().getConfiguration().locale; return locale.toLanguageTag(); }

参考 android源码中设置语言的代码相关位置 Android实践 – 设置系统日期时间和时区

最新回复(0)