Android 系统设置中显示设置之屏幕旋转和字体设置篇

继上一篇学习了android系统设置的UI内容后,今天学习android设置中有关显示设置的内容。

当我们点击系统设置的显示选项的时候,会跳转到有关系统显示设置的页面,该页面便是DisplaySettings.java,这个类的继承关系为:

java Font 设置字体 java中设置字体_displaysettings.java

原来它也是PreferenceFragment的子类,至于PreferenceFragment怎么使用,请详见:

我们看到在DisplaySettings的oncreate方法中addPreferencesFromResource(R.xml.display_settings)将我们所看到的界面加载进来,界面的内容就是display_settings.xml,具体定义如下:

java Font 设置字体 java中设置字体_ide_02

java Font 设置字体 java中设置字体_displaysettings.java_03

1 
2 android:title="@string/display_settings"
3 xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
4
5 
7 android:persistent="false"/>
8
9 
11 android:title="@string/wallpaper_settings_title"
12 android:fragment="com.android.settings.WallpaperTypeSettings" />
13
14 
16 android:title="@string/accelerometer_title"/>
17
18 
20 android:title="@string/screen_timeout"
21 android:summary="@string/screen_timeout_summary"
22 android:persistent="false"
23 android:entries="@array/screen_timeout_entries"
24 android:entryValues="@array/screen_timeout_values" />
25
26 
28 android:title="@string/screensaver_settings_title"
29 android:fragment="com.android.settings.DreamSettings" />
30
31 
33 android:title="@string/title_font_size"
34 android:summary="@string/summary_font_size"
35 android:entries="@array/entries_font_size"
36 android:entryValues="@array/entryvalues_font_size"
37 android:dialogTitle="@string/dialog_title_font_size" />
38
39 
41 android:title="@string/notification_pulse_title"
42 android:persistent="false" />
43
44 
46 android:title="@string/wifi_display_settings_title"
47 android:fragment="com.android.settings.wfd.WifiDisplaySettings" />
48
49

View Code

java Font 设置字体 java中设置字体_android_04

设置界面说完了,我们就来看看具体代码是如何设置的。

1.首先了解一下自动旋转的设置

从界面读取该preference并判断是否进行显示

1 @Override2 public voidonCreate(Bundle savedInstanceState) {3 super.onCreate(savedInstanceState);4 ContentResolver resolver =getActivity().getContentResolver();5

6 addPreferencesFromResource(R.xml.display_settings);7

8 //从界面中找到设置旋转的preference

9 mAccelerometer =(CheckBoxPreference) findPreference(KEY_ACCELEROMETER);10 mAccelerometer.setPersistent(false);11 //判断设备是否支持旋转和设置

12 if (!RotationPolicy.isRotationSupported(getActivity())13 ||RotationPolicy.isRotationLockToggleSupported(getActivity())) {14 //If rotation lock is supported, then we do not provide this option in15 //Display settings. However, is still available in Accessibility settings,16 //if the device supports rotation.

17 getPreferenceScreen().removePreference(mAccelerometer);18 }

接下来我们看看如何判断设备是否支持旋转:

java Font 设置字体 java中设置字体_ide_02

java Font 设置字体 java中设置字体_displaysettings.java_03

1 /**

2 * Gets whether the device supports rotation. In general such a3 * device has an accelerometer and has the portrait and landscape4 * features.5 * //这里判断设备是否支持旋转,通常情况下设备都支持加速和横竖屏属性6 *@paramcontext Context for accessing system resources.7 *@returnWhether the device supports rotation.8 */

9 public static booleanisRotationSupported(Context context) {10 PackageManager pm =context.getPackageManager();11 returnpm.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER)12 &&pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT)13 &&pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);14 }15

16 /**

17 * Returns true if the device supports the rotation-lock toggle feature18 * in the system UI or system bar.19 * //这里的意思是讲设备是否支持快捷方式设置旋转20 * When the rotation-lock toggle is supported, the "auto-rotate screen" option in21 * Display settings should be hidden, but it should remain available in Accessibility22 * settings.23 */

24 public static booleanisRotationLockToggleSupported(Context context) {25 returnisRotationSupported(context)26 && context.getResources().getConfiguration().smallestScreenWidthDp >= 600;27 }

View Code

以上的代码通过RotationPolicy类判断设备是否支持旋转和是否支持快捷设置了。那设备是如何获取设备的状态又将将修改的内容设置到哪里去了呢?

1 /**

2 * 更新该preference的状态,从RotationPolicy.isRotationLocked中读取3 */

4 private voidupdateAccelerometerRotationCheckbox() {5 if (getActivity() == null) return;6

7 mAccelerometer.setChecked(!RotationPolicy.isRotationLocked(getActivity()));8 }

1 /**

2 * Returns true if rotation lock is enabled.3 * 如果旋转旋转锁可用就返回true,调用的地方取反在界面上显示就是没有选中。4 * 其中我们也看到我们的旋转属性是从Settings.System中获取。5 */

6 public static booleanisRotationLocked(Context context) {7 returnSettings.System.getIntForUser(context.getContentResolver(),8 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) == 0;9 }

Settings.system中的Settings是专门用来存储和对于属性的类,它的实现用的是ContentProvider进行存储和读取的。具体的我们查看在framework中找到SettingsProvider.java和Settings.java,他们都存储在framework/base/core/java/android/provider/中,具体的实现请百度。

说完了读取,我们接下来学习下如何设置旋转:

1 @Override2 public booleanonPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {3 if (preference ==mAccelerometer) {4 //如果当前的preference是设置旋转的preference,调用RotationPolicy的setRotationLockForAccessibility函数进行设置

5 RotationPolicy.setRotationLockForAccessibility(6 getActivity(), !mAccelerometer.isChecked());7 } else if (preference ==mNotificationPulse) {8 boolean value =mNotificationPulse.isChecked();9 Settings.System.putInt(getContentResolver(), Settings.System.NOTIFICATION_LIGHT_PULSE,10 value ? 1 : 0);11 return true;12 }13 return super.onPreferenceTreeClick(preferenceScreen, preference);14 }

java Font 设置字体 java中设置字体_ide_02

java Font 设置字体 java中设置字体_displaysettings.java_03

1 /**

2 * Enables or disables rotation lock and adjusts whether the rotation lock toggle3 * should be hidden for accessibility purposes.4 *5 * Should be used by Display settings and Accessibility settings.6 */

7 public static void setRotationLockForAccessibility(Context context, final booleanenabled) {8 //将用户设置的内容设置到Settings.system中

9 Settings.System.putIntForUser(context.getContentResolver(),10 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0,11 UserHandle.USER_CURRENT);12

13 AsyncTask.execute(newRunnable() {14 @Override15 public voidrun() {16 try{17 IWindowManager wm =WindowManagerGlobal.getWindowManagerService();18 if(enabled) {19 //不允许旋转,Surface.ROTATION_0--->旋转角度为0

20 wm.freezeRotation(Surface.ROTATION_0);21 } else{22 //允许进行自动旋转

23 wm.thawRotation();24 }25 } catch(RemoteException exc) {26 Log.w(TAG, "Unable to save auto-rotate setting");27 }28 }29 });30 }

View Code

以上的代码的作用是点击该preference,修改对应的状态并根据修改后的状态设置快捷设置中旋转的开关状态。其中我们发现了IwindowManager通过调用freezeRotation和thawRotation控制屏幕是否旋转等。

详情也可以参考:

2.  字体大小的读取与设置

字体大小的读取操作

1 /**

2 * 读取系统字体的大小,这里主要用到Configuration类,这个类中包含了字体大小的属性fontScale3 * 至于ActivityManagerNative.getDefault()的使用请百度或者参考:4 *

5 */

6 public voidreadFontSizePreference(ListPreference pref) {7 try{8 mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());9 } catch(RemoteException e) {10 Log.w(TAG, "Unable to retrieve font size");11 }12

13 //mark the appropriate item in the preferences list

14 int index =floatToIndex(mCurConfig.fontScale);15 pref.setValueIndex(index);16

17 //report the current size in the summary text

18 final Resources res =getResources();19 String[] fontSizeNames =res.getStringArray(R.array.entries_font_size);20 pref.setSummary(String.format(res.getString(R.string.summary_font_size),21 fontSizeNames[index]));22 }

字体的写入过程

在DisplaySettings.java中对字体的设置涉及到了几个地方,首先:

1 @Override2 public booleanonPreferenceClick(Preference preference) {3 if (preference ==mFontSizePref) {4 //首先判断系统是否是多用户模式,如果是则弹出提示框提示是否进行字体的修改

5 if(Utils.hasMultipleUsers(getActivity())) {6 showDialog(DLG_GLOBAL_CHANGE_WARNING);7 return true;8 } else{9 //preference消失,然后调转到onPreferenceChange进行处理

10 mFontSizePref.click();11 }12 }13 return false;14 }

java Font 设置字体 java中设置字体_ide_02

java Font 设置字体 java中设置字体_displaysettings.java_03

1 public booleanonPreferenceChange(Preference preference, Object objValue) {2 final String key =preference.getKey();3 if(KEY_SCREEN_TIMEOUT.equals(key)) {4 int value =Integer.parseInt((String) objValue);5 try{6 Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, value);7 updateTimeoutPreferenceDescription(value);8 } catch(NumberFormatException e) {9 Log.e(TAG, "could not persist screen timeout setting", e);10 }11 }12 if(KEY_FONT_SIZE.equals(key)) {13 //该函数对字体进行设置

14 writeFontSizePreference(objValue);15 }16

17 return true;18 }

View Code

1 public voidwriteFontSizePreference(Object objValue) {2 try{3 //对fontScale进行修改,然后调用updatePersistentConfiguration进行设置

4 mCurConfig.fontScale =Float.parseFloat(objValue.toString());5 ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);6 } catch(RemoteException e) {7 Log.w(TAG, "Unable to save font size");8 }9 }

我们默认的字体大小有哪些呢?

java Font 设置字体 java中设置字体_ide_02

java Font 设置字体 java中设置字体_displaysettings.java_03

1

2 Small

3 Normal

4 Large

5 Huge

6

7

8

9 0.85

10 1.0

11 1.15

12 1.30

13

View Code

通过以上分析,我们了解到android系统对字体大小的修改主要用到了ActivityManagerNative.getDefault().getConfiguration()得到Configuration对象,而该对象中正好保存了字体大小的属性fontScale。当我们修改字体大小的时候,只要修改Configuration中的fontScale,并调用updatePersistentConfiguration函数就可以了。

今天先到这里吧!后续会把其他的显示设置加进来。你的支持是我不懈的动力,当然不喜勿喷!2014-07-28 16:51:03