繼上一篇學習了android系統設置的UI內容後,今天學習android設置中有關顯示設置的內容。
當咱們點擊系統設置的顯示選項的時候,會跳轉到有關係統顯示設置的頁面,該頁面即是DisplaySettings.java,這個類的繼承關係爲:
原來它也是PreferenceFragment的子類,至於PreferenceFragment怎麼使用,請詳見:http://blog.csdn.net/zwq1457/article/details/8490004html
咱們看到在DisplaySettings的oncreate方法中addPreferencesFromResource(R.xml.display_settings)將咱們所看到的界面加載進來,界面的內容就是display_settings.xml,具體定義以下:java
1 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 2 android:title="@string/display_settings" 3 xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"> 4 5 <com.android.settings.BrightnessPreference 6 android:title="@string/brightness" 7 android:persistent="false"/> 8 9 <PreferenceScreen 10 android:key="wallpaper" 11 android:title="@string/wallpaper_settings_title" 12 android:fragment="com.android.settings.WallpaperTypeSettings" /> 13 14 <CheckBoxPreference 15 android:key="accelerometer" 16 android:title="@string/accelerometer_title"/> 17 18 <ListPreference 19 android:key="screen_timeout" 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 <PreferenceScreen 27 android:key="screensaver" 28 android:title="@string/screensaver_settings_title" 29 android:fragment="com.android.settings.DreamSettings" /> 30 31 <com.android.settings.WarnedListPreference 32 android:key="font_size" 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 <CheckBoxPreference 40 android:key="notification_pulse" 41 android:title="@string/notification_pulse_title" 42 android:persistent="false" /> 43 44 <PreferenceScreen 45 android:key="wifi_display" 46 android:title="@string/wifi_display_settings_title" 47 android:fragment="com.android.settings.wfd.WifiDisplaySettings" /> 48 49 </PreferenceScreen>
設置界面說完了,咱們就來看看具體代碼是如何設置的。
從界面讀取該preference並判斷是否進行顯示
1 @Override 2 public void onCreate(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 in 15 // Display settings. However, is still available in Accessibility settings, 16 // if the device supports rotation. 17 getPreferenceScreen().removePreference(mAccelerometer); 18 }
接下來咱們看看如何判斷設備是否支持旋轉:
1 /** 2 * Gets whether the device supports rotation. In general such a 3 * device has an accelerometer and has the portrait and landscape 4 * features. 5 * //這裏判斷設備是否支持旋轉,一般狀況下設備都支持加速和橫豎屏屬性 6 * @param context Context for accessing system resources. 7 * @return Whether the device supports rotation. 8 */ 9 public static boolean isRotationSupported(Context context) { 10 PackageManager pm = context.getPackageManager(); 11 return pm.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 feature 18 * in the system UI or system bar. 19 * //這裏的意思是講設備是否支持快捷方式設置旋轉 20 * When the rotation-lock toggle is supported, the "auto-rotate screen" option in 21 * Display settings should be hidden, but it should remain available in Accessibility 22 * settings. 23 */ 24 public static boolean isRotationLockToggleSupported(Context context) { 25 return isRotationSupported(context) 26 && context.getResources().getConfiguration().smallestScreenWidthDp >= 600; 27 }
以上的代碼經過RotationPolicy類判斷設備是否支持旋轉和是否支持快捷設置了。那設備是如何獲取設備的狀態又將將修改的內容設置到哪裏去了呢?
1 /** 2 * 更新該preference的狀態,從RotationPolicy.isRotationLocked中讀取 3 */ 4 private void updateAccelerometerRotationCheckbox() { 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 boolean isRotationLocked(Context context) { 7 return Settings.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 @Override 2 public boolean onPreferenceTreeClick(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 }
1 /** 2 * Enables or disables rotation lock and adjusts whether the rotation lock toggle 3 * 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 boolean enabled) { 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(new Runnable() { 14 @Override 15 public void run() { 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 }
以上的代碼的做用是點擊該preference,修改對應的狀態並根據修改後的狀態設置快捷設置中旋轉的開關狀態。其中咱們發現了IwindowManager經過調用freezeRotation和thawRotation控制屏幕是否旋轉等。
詳情也能夠參考:http://blog.csdn.net/siobhan/article/details/8526006
1 /** 2 * 讀取系統字體的大小,這裏主要用到Configuration類,這個類中包含了字體大小的屬性fontScale 3 * 至於ActivityManagerNative.getDefault()的使用請百度或者參考: 4 * http://www.cnblogs.com/bastard/archive/2012/05/25/2517522.html 5 */ 6 public void readFontSizePreference(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中對字體的設置涉及到了幾個地方,首先:android
1 @Override 2 public boolean onPreferenceClick(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 }
1 public boolean onPreferenceChange(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 }
1 public void writeFontSizePreference(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 }
咱們默認的字體大小有哪些呢?app
1 <string-array name="entries_font_size"> 2 <item msgid="6490061470416867723">Small</item> 3 <item msgid="3579015730662088893">Normal</item> 4 <item msgid="1678068858001018666">Large</item> 5 <item msgid="490158884605093126">Huge</item> 6 </string-array> 7 8 <string-array name="entryvalues_font_size" translatable="false"> 9 <item>0.85</item> 10 <item>1.0</item> 11 <item>1.15</item> 12 <item>1.30</item> 13 </string-array>
經過以上分析,咱們瞭解到android系統對字體大小的修改主要用到了ActivityManagerNative.getDefault().getConfiguration()獲得Configuration對象,而該對象中正好保存了字體大小的屬性fontScale。當咱們修改字體大小的時候,只要修改Configuration中的fontScale,並調用updatePersistentConfiguration函數就能夠了。 今天先到這裏吧!後續會把其餘的顯示設置加進來。你的支持是我不懈的動力,固然不喜勿噴!2014-07-28 16:51:03