1. 程式人生 > >Android系統Settings設定模組

Android系統Settings設定模組

Settings設定模組UI介紹

FrameWork開發之路首先得玩得轉系統APP,個人是在Android5.0的基礎上進行定製,Settings模組分為兩個部分:
packages\app\Settings 下的APP程式碼部分
frameworks/base/packages/SettingsProvider/ 資料庫
frameworks/base/core/java/android/provider/Settings.java
首先從APP程式碼部分入手,UI介面架構是有3部分組成實現可配置可擴充套件,先理解PreferenceFragment, PreferenceScreen

,PreferenceCategory, Preference的關係,介紹的最詳細的就是谷歌官方文件了,參照連結
我這邊首先將的是如何自定義PreferenceCategory和自定義Preference,首先來看系統如何來操作的,參考設定儲存部分的介面
這裡寫圖片描述

packages\apps\Settings\src\com\android\settings\deviceinfo\Memory.java就是fragment介面
###fragment核心程式碼塊

@Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        final Context context = getActivity();
        '''preferenceFragment佈局檔案'''
addPreferencesFromResource(R.xml.device_info_memory); for (StorageVolume volume : storageVolumes) { if (mMemoryExts.isAddPhysicalCategory(volume)) { addCategory(StorageVolumePreferenceCategory.buildForPhysical(context, volume)); } } } private void addCategory(StorageVolumePreferenceCategory category) { mCategories.add(category); '''add多個category模組'''
getPreferenceScreen().addPreference(category); category.init(); }
對應的XMl,device_info_xml檔案內容:

`<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
    android:title="@string/storage_settings"
    settings:keywords="@string/keywords_storage">
 </PreferenceScreen>


可以看出預設儲存器,遙控儲存器,總容量都是作為preference合併到一個category,然後add到preferenceScreen裡面,下面來看PreferenceCategory怎麼自定義,packages\apps\Settings\src\com\android\settings\deviceinfo下的StorageVolumePreferenceCategory.java

public class StorageVolumePreferenceCategory extends PreferenceCategory {
 private StorageVolumePreferenceCategory(Context context, StorageVolume volume) {
        super(context);

        mVolume = volume;
        mMeasure = StorageMeasurement.getInstance(context, volume);
        mResources = context.getResources();
        mStorageManager = StorageManager.from(context);
        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);

        mCategoryExts = new StorageVolumePreferenceCategoryExts(context, mVolume);
        mCategoryExts.setVolumeTitle(this);
    }

    private StorageItemPreference buildItem(int titleRes, int colorRes) {
        return new StorageItemPreference(getContext(), titleRes, colorRes);
    }

    public void init() {
        final Context context = getContext();
        '''遙控器儲存作為自定義的Preference'''
        mUsageBarPreference = new UsageBarPreference(context);
        mUsageBarPreference.setOrder(ORDER_USAGE_BAR);
        addPreference(mUsageBarPreference);
        '''總容量作為自定義的Preference'''
        mItemTotal = buildItem(R.string.memory_size, 0);
        mItemAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
        addPreference(mItemTotal);
        addPreference(mItemAvailable);
        '''各個類別檔案儲存作為自定義的Preference'''
        mItemApps = buildItem(R.string.memory_apps_usage, R.color.memory_apps_usage);
        mItemDcim = buildItem(R.string.memory_dcim_usage, R.color.memory_dcim);
        mItemMusic = buildItem(R.string.memory_music_usage, R.color.memory_music);
        mItemDownloads = buildItem(R.string.memory_downloads_usage, R.color.memory_downloads);
        mItemCache = buildItem(R.string.memory_media_cache_usage, R.color.memory_cache);
        mItemMisc = buildItem(R.string.memory_media_misc_usage, R.color.memory_misc);

        mItemCache.setKey(KEY_CACHE);

        /** M: CR ALPS01309473, Set storageItem [email protected]{*/
        mItemApps.setKey(KEY_APPS);
        mItemDcim.setKey(KEY_DCIM);
        mItemMusic.setKey(KEY_MUSIC);
        mItemDownloads.setKey(KEY_DOWNLOADS);
        mItemMisc.setKey(KEY_MISC);
        /** @} */

        final boolean showDetails = mVolume == null || mVolume.isPrimary();
        if (showDetails) {
            if (showUsers) {
                addPreference(new PreferenceHeader(context, currentUser.name));
            }
           '''Preference 新增到Category的過程'''
            addPreference(mItemApps);
            addPreference(mItemDcim);
            addPreference(mItemMusic);
            addPreference(mItemDownloads);
            addPreference(mItemCache);
            addPreference(mItemMisc);
        }
     }

}

下面看如何自定義各種UI效果的Preference,本質就是自定義View披上一層外套,從簡單的入手,音量設定的preference個人認為好理解
\packages\apps\Settings\src\com\android\audioprofile\AudioProfilePreference.java

public class AudioProfilePreference extends Preference {
 public AudioProfilePreference(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);

        mContext = context;

        mInflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        // get the title from audioprofile_settings.xml
         '''Preference屬性Title的設定'''
        if (super.getTitle() != null) {
            mPreferenceTitle = super.getTitle().toString();
        }

        // get the summary from audioprofile_settings.xml
          '''Preference屬性Summary副標題的設定'''
        if (super.getSummary() != null) {
            mPreferenceSummary = super.getSummary().toString();
        }

        mProfileManager = (AudioProfileManager) context
                .getSystemService(Context.AUDIO_PROFILE_SERVICE);
      '''Preference屬性Key本質就是SharedPreference種的Key設定'''
        mKey = getKey();

        mExt = UtilsExt.getAudioProfilePlgin(context);
    }
    '''PreferenceUI效果'''
    @Override
    public View onCreateView(ViewGroup parent) {
        Xlog.d(XLOGTAG, TAG + "onCreateView " + getKey());
        View view = mExt.createView(R.layout.audio_profile_item);

        mCheckboxButton = (RadioButton) mExt
                .getPrefRadioButton(R.id.radiobutton);
        mTextView = (TextView) mExt.getPreferenceTitle(R.id.profiles_text);
        mSummary = (TextView) mExt.getPreferenceSummary(R.id.profiles_summary);
      }

}

看一下Preference的UI xml檔案

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    >

    <LinearLayout android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"/>  
        <RadioButton 
            android:id="@+id/radiobutton" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_gravity="center"
            android:orientation="vertical"
            android:focusable="false"/>
     />

哈哈,本質就是自定義View了
還有一個小的知識點:官方文件介紹PreferenceScreen跳轉Activity的時候沒有介紹到Intent怎麼給Activity傳值,所以我就貼上這個小的知識點

<PreferenceScreen android:key="toggle_storage_settings"
                      android:title="@string/storage_settings">
            <intent android:action="settings.advanced.fragment"
                    android:targetPackage="com.android.settings">
            <extra android:name="Zhongqi.Shao" android:value="com.android.settings.deviceinfo.Memory"/>
            </intent>
    </PreferenceScreen> 

到這應該理解Settings UI效果中的每一個元素關係,現在可以看Settings佈局UI效果的實現原理

這裡寫圖片描述

packages\apps\Settings\src\com\android\settings\SettingsActivity.java
啟動的Activity是繼承SettingsActivity的Settings.java,參見SettingsActivity.onCreate()函式本質就是Framelayout切換Fragment的效

    @Override
    protected void onCreate(Bundle savedState) {
        super.onCreate(savedState);
        '''就是空空的FrameLayout'''
         setContentView(mIsShowingDashboard ?
                R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
           '''中間程式碼省略'''       
          switchToFragment(DashboardSummary.class.getName(), null, false, false,
                        mInitialTitleResId, mInitialTitle, false);
      }

下面來看packages\apps\Settings\src\com\android\settings\dashboardDashboardSummary.java的程式碼

private void rebuildUI(Context context) {
        long start = System.currentTimeMillis();
        final Resources res = getResources();

        mDashboard.removeAllViews();
        '''又回到SettingsActivity.getDashboardCategories()'''  
        List<DashboardCategory> categories =
                ((SettingsActivity) context).getDashboardCategories(true);
 }

'''SettingsActivity中getDashboardCategories()實現'''  
public List<DashboardCategory> getDashboardCategories(boolean forceRefresh) {
        if (forceRefresh || mCategories.size() == 0) {
            buildDashboardCategories(mCategories);
        }
        return mCategories;
 }

  private void buildDashboardCategories(List<DashboardCategory> categories) {
        categories.clear();
        '''重點 通過解析xml來實現配置載入fragment'''  
        loadCategoriesFromResource(R.xml.dashboard_categories, categories);
        updateTilesList(categories);
    }
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<dashboard-categories
        xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- WIRELESS and NETWORKS -->
    <dashboard-category
            android:id="@+id/wireless_section"
            android:title="@string/header_category_wireless_networks" >

        <!-- Wifi -->
        <dashboard-tile
                android:id="@+id/wifi_settings"
                android:title="@string/wifi_settings_title"
                android:fragment="com.android.settings.wifi.WifiSettings"
                android:icon="@drawable/ic_settings_wireless"
                />

        <!--HetComm-->
        <dashboard-tile
                android:id="@+id/hetcomm_settings"
                android:icon="@drawable/ic_settings_hetcomm"
                android:title="@string/hetcom_setting_title">
            <intent android:action="com.android.settings.HETCOMM_SETTINGS" />
        </dashboard-tile>

        <!-- Bluetooth -->
        <dashboard-tile
                android:id="@+id/bluetooth_settings"
                android:title="@string/bluetooth_settings_title"
                android:fragment="com.android.settings.bluetooth.BluetoothSettings"
                android:icon="@drawable/ic_settings_bluetooth2"
                />

        <!-- Hotknot -->
        <dashboard-tile
                android:id="@+id/hotknot_settings"
                android:title="@string/hotknot_settings_title"
                android:fragment="com.mediatek.settings.hotknot.HotKnotSettings"
                android:icon="@drawable/ic_settings_hotknot" 
                />

        <!-- SIM Cards -->
        <dashboard-tile
                android:id="@+id/sim_settings"
                android:title="@string/sim_settings_title"
                android:fragment="com.android.settings.sim.SimSettings"
                android:icon="@drawable/ic_sim_sd"
                />

        <!-- Data Usage -->
        <dashboard-tile
                android:id="@+id/data_usage_settings"
                android:title="@string/data_usage_summary_title"
                android:fragment="com.android.settings.DataUsageSummary"
                android:icon="@drawable/ic_settings_data_usage"
                />

        <!-- Operator hook -->
        <!--modify by zhongqi.shao on 2016-09-12 start
        <dashboard-tile
                android:id="@+id/operator_settings"
                android:fragment="com.android.settings.WirelessSettings" >
            <intent android:action="com.android.settings.OPERATOR_APPLICATION_SETTING" />
        </dashboard-tile>

        <dashboard-tile
                android:id="@+id/wireless_settings"
                android:title="@string/radio_controls_title"
                android:fragment="com.android.settings.WirelessSettings"
                android:icon="@drawable/ic_settings_more"

                />modify by zhongqi.shao on 2016-09-12 end-->

    </dashboard-category>

    <!-- DEVICE -->
    <dashboard-category
            android:id="@+id/device_section"
            android:title="@string/header_category_device" >

        <!-- Home -->
        <dashboard-tile
                android:id="@+id/home_settings"
                android:title="@string/home_settings"
                android:fragment="com.android.settings.HomeSettings"
                android:icon="@drawable/ic_settings_home"
                />

        <!-- Display -->
        <dashboard-tile
                android:id="@+id/display_settings"
                android:title="@string/display_settings"
                android:fragment="com.android.settings.DisplaySettings"
                android:icon="@drawable/ic_settings_display"
                />

        <!-- Notifications -->
        <dashboard-tile
                android:id="@+id/notification_settings"
                android:title="@string/notification_settings"
                android:fragment="com.mediatek.audioprofile.AudioProfileSettings"
                android:icon="@drawable/ic_settings_notifications"
                />

        <!--modify by zhongqi.shao on 2016-09-13 start-->
        <!-- Storage -->
        <!--<dashboard-tile
                android:id="@+id/storage_settings"
                android:title="@string/storage_settings"
                android:fragment="com.android.settings.deviceinfo.Memory"
                android:icon="@drawable/ic_settings_storage"
                />-->
        <!--modify by zhongqi.shao on 2016-09-13 end-->

        <!-- Battery -->
        <dashboard-tile
                android:id="@+id/battery_settings"
                android:title="@string/power_usage_summary_title"
                android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
                android:icon="@drawable/ic_settings_battery"
                />

        <!-- Application Settings -->
        <dashboard-tile
                android:id="@+id/application_settings"
                android:title="@string/applications_settings"
                android:fragment="com.android.settings.applications.ManageApplications"
                android:icon="@drawable/ic_settings_applications"
                />

        <!-- Manage users -->
        <dashboard-tile
                android:id="@+id/user_settings"
                android:title="@string/user_settings_title"
                android:fragment="com.android.settings.users.UserSettings"
                android:icon="@drawable/ic_settings_multiuser"
                />

        <!-- Manage NFC payment apps -->
        <dashboard-tile
                android:id="@+id/nfc_payment_settings"
                android:title="@string/nfc_payment_settings_title"
                android:fragment="com.android.settings.nfc.PaymentSettings"
                android:icon="@drawable/ic_settings_nfc_payment"
                />

        <!-- Manufacturer hook -->
        <!--modify by zhongqi.shao on 2016-09-12
        <dashboard-tile
                android:id="@+id/manufacturer_settings"
                android:fragment="com.android.settings.WirelessSettings">
            <intent android:action="com.android.settings.MANUFACTURER_APPLICATION_SETTING" />
        </dashboard-tile>-->

    </dashboard-category>

    <!-- PERSONAL -->
    <dashboard-category
            android:id="@+id/personal_section"
            android:title="@string/header_category_personal" >

        <!-- Location -->
        <dashboard-tile
                android:id="@+id/location_settings"
                android:title="@string/location_settings_title"
                android:fragment="com.android.settings.location.LocationSettings"
                android:icon="@drawable/ic_settings_location"
                />

        <!-- Security -->
        <dashboard-tile
                android:id="@+id/security_settings"
                android:title="@string/security_settings_title"
                android:fragment="com.android.settings.SecuritySettings"
                android:icon="@drawable/ic_settings_security"
                />

        <!-- Account -->
        <dashboard-tile
                android:id="@+id/account_settings"
                android:title="@string/account_settings_title"
                android:fragment="com.android.settings.accounts.AccountSettings"
                android:icon="@drawable/ic_settings_accounts"
                />

        <!-- Language -->
        <dashboard-tile
                android:id="@+id/language_settings"
                android:title="@string/language_settings"
                android:fragment="com.android.settings.inputmethod.InputMethodAndLanguageSettings"
                android:icon="@drawable/ic_settings_language"
                />

        <!-- Backup and reset -->
        <dashboard-tile
                android:id="@+id/privacy_settings"
                android:title="@string/privacy_settings"
                android:fragment="com.android.settings.PrivacySettings"
                android:icon="@drawable/ic_settings_backup"
                />

    </dashboard-category>


</dashboard-categories>

到這基本UI可以說是過來一遍,下面會來記錄我這邊是怎麼來深度定製

相關推薦

Android系統Settings設定模組

Settings設定模組UI介紹 FrameWork開發之路首先得玩得轉系統APP,個人是在Android5.0的基礎上進行定製,Settings模組分為兩個部分: packages\app\Settings 下的APP程式碼部分 fram

Android系統settings裡新增設定選項

目的:在通話設定選單下,新增一dect設定選單,裡面再新增一checkBOxPreference 來使能硬體模組。 ------------------------- 目前做的專案,需要在系統settings裡面新增一選項來使能硬體模組,裡面涉及到的preference知識

Android系統---Settings

最近在研究Android的Settings原始碼,先看一下原始碼的目錄結構。大概967左右個檔案,是不是及其頭疼而且無從下手?待我娓娓道來~~~~~ 1,初識Settings 首先,這麼多檔案,到底哪個檔案是主介面呢?在Settings目錄下找到Androidmanifes

android 原生camera——設定模組修改

, 此篇部落格是記一次客戶需求修改,從上週五到現在正好一週時間,期間的各種酸爽,就不說了,還是來看大家關注的技術問題吧。 首先看下以前效果和修改後的效果: 修改前:修改後: 不知道有沒有看明白,我在簡單說下,沒修改前Camera 設定中是有兩個選項的一個負責預

Android 系統 Settings 啟動流程詳解

Settings簡介   Settings 是 Android 系統自帶的一個很重要的應用,給使用者提供了操作 Android 系統功能的介面。它裡面包含了 Wireless & network,device,personal 以及 system 等幾

Android系統設定TextView的行間距(非行高)

Android系統中TextView預設顯示中文時會比較緊湊,不是很美觀。為了讓每行保持一定的行間距,可以設定屬性android:lineSpacingExtra或android:lineSpacingMultiplier。 1、android:lineSpacingEx

Android系統預設設定(開機第一次後的設定)(一)

http://www.cnblogs.com/sardine /frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.jpg /packages/wallpapers/Basic/src/com/android/wallpaper/nex

android-如何在系統settings裡新增設定選項

版本:2.3.1 目的:在通話設定選單下,新增一dect設定選單,裡面再新增一checkBOxPreference 來使能硬體模組。 ------------------------- 目前做的專案,需要在系統settings裡面新增一選項來使能硬體模組,裡面涉及到的pre

Android中的android.provider.Settings.System系統屬性設定

Content Provider中的Setting.System表格記憶體儲了很多系統屬性的值,以鍵值對的形式存在! 可以對如下的變數進行設定 通過如下的函式可以對其進行讀寫: static void (ContentResolver cr, Configurati

Android系統設定settings應用學習(一)--允許未知來源應用安裝

 settings,是Android系統應用--設定的原始碼,包名稱為:com.android.settings  安全設定程式碼:SecuritySettings.java /* * Copyright (C) 2007 The Android Open Source

Android系統設定預設值大全

一、是否有預設值 在尋找一個開關的預設值時,首先要明白一點,該開關是否存在預設值,以及該開關狀態是否有狀態儲存(一般狀態儲存在settings的db中)。 判斷條件: 在reboot(重啟)之後開關狀態仍舊儲存或者是在reset(恢復出廠設定)之後開關狀態恢復到預設的,才能找到預設值。

AndroidSettings預設值的設定

設定Settings的預設值有兩種方式 A. 在獲取是有一個介面可以進行預設值設定,當資料庫中查詢不到該值時,就會返回傳入的預設值。 public static int getInt(ContentResolver cr, String name, int def) {   

Android 系統原始碼不編譯xxxTests模組的mk檔案註釋

1. 編譯xxxTests模組導致的編譯不過 build/core/Makefile:2789: warning: ignoring old commands for target `out/target/product/sp9832e_op54_go/sp9832e_op54_g

android系統版本6.0及以上設定沉浸式狀態列

系統版本6.0及以上設定沉浸式狀態列程式碼。   requestWindowFeature(Window.FEATURE_NO_TITLE); //系統版本6.0及以上設定沉浸式狀態列 if (RomUtil.hasM()) { int flag = getWindow().get

Android O Settings原始碼流程分析(資料載入之獲取及修改預設設定屬性值)

Android O Settings  靜態介面篇 介面渲染篇 資料載入篇之一級選單 資料載入篇之二級選單 資料載入篇之獲取及修改預設設定屬性值 搜尋欄篇 載入預設設定值及修改:(涉及SettingsProvider) 示例:(裝置自動亮

Android 8.1 非系統程序設定系統域屬性問題

1. 程序間通過設定屬性進行互動 Android 系統開發中經常需要通過屬性在各個程序間傳遞資訊,通過一個程序 set_property,另一個程序 get_property 達到程序間通訊的需求。 屬性獲取沒有限制,但是如果需要程序可以進行設定屬性操作,則需要做一些處理。因為在

AndroidSettings模組

Settings就是我們常說的手機設定,程式碼路徑 packages\apps\Settings 使用者常用操作有: 開/關 Wifi 選項 開/關 藍芽BT 選項 開/關 資料流量 選項 開/關 電池電量百分比 選項 螢幕亮度 調整 滅屏時間 調整 另外一些S

Android應用內設定多語言,可隨系統語言改變而改變,也可設定app為固定語言不受系統語言影響

轉載請標明出處: https://blog.csdn.net/m0_38074457/article/details/84993366,本文出自:【陳少華的部落格】 一、效果圖 https://github.com/hnsycsxhzcsh/MultiLanguage/blob/mas

【分享】迅為iTOP4412開發板-Android系統螢幕旋轉設定

1.1概述 Android4.0,Androd4.4原始碼可以編譯成手機模式和平板模式,訊為iTop4412 開發平臺 的Android系統預設編譯為平板模式。客戶需要根據自己的產品設計及應用環境,切換螢幕 的顯示方向,或者固定好一個顯示方向,例如產品中使用不同解析度的顯

android 7.1系統語言設定和5.1.1不同

//7.1參考 \frameworks\base\core\java\com\android\internal\app\LocalePicker.javapublic static void updateLocale(Locale locale) {updateLocales