1. 程式人生 > >Android 7.0 settings中新增新選單

Android 7.0 settings中新增新選單

需求:

在設定中,新增一級選單項,在裝置中加入“按鍵交換”,此項選單與“顯示”並列

由於android 7.0 settings網上資料還沒有,此需求在高通技術支援的幫助下加上自己的分析才實現(對高通技術支援小夥表示感謝),實現後發現特別簡單,但是實現前一直沒頭緒,希望記下來能對網友有所幫助

只需實現Activity,寫佈局檔案後,在AndroidManifest.xml中配置即可,配置如下

<activity android:name="HardKey"
                android:label="@string/hardkey_switch"
                android:icon="@drawable/a2_zuo_you_jiaohuan_2"
                android:taskAffinity="">
            <intent-filter android:priority="1">
                <action android:name="com.android.settings.HARDKEY" />
                <action android:name="android.settings.HARDKEY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.VOICE_LAUNCH" />
                <category android:name="com.android.settings.SHORTCUT" />
            </intent-filter>
            <intent-filter android:priority="9">
                <action android:name="com.android.settings.action.SETTINGS" />
            </intent-filter>
            <meta-data android:name="com.android.settings.category"
                android:value="com.android.settings.category.device" />
            <meta-data android:name="com.android.settings.ACTIVITY_ACTION"
                android:value="com.android.settings.HardKey" />
            
            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                android:value="true" />
        </activity>


其中HarKey.java是一個Activity檔案,直接繼承了Activity

設定下的一級選單必須要有此intent,SettingsActivity檔案會根據此filter過濾

 android:priority="9"加這個屬性與位置順序有關,即兩個同樣的選單,哪個在前,哪個在後

<intent-filter android:priority="9">
                <action android:name="com.android.settings.action.SETTINGS" />
            </intent-filter>

此meta表示 選單項在 device的分類中

<meta-data android:name="com.android.settings.category"
                android:value="com.android.settings.category.device" />

表示此檔案是一個Activity

<meta-data android:name="com.android.settings.ACTIVITY_ACTION"
                android:value="com.android.settings.HardKey" />

如果是一個fragment,則用

<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                android:value="com.android.settings.DisplaySettings" />

這個必須要有,不然不會顯示在設定選單項中

<intent-filter android:priority="9">
                <action android:name="com.android.settings.action.SETTINGS" />
            </intent-filter>

這個屬性也要加,因為其他的選單項都有(新增新的類似功能時,對比已有功能實現),具體還不知道起什麼作用,有知道的可以留言

<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                android:value="true" />


效果圖


原圖


後續將介紹android 7.0 settings原始碼流程

2017年10月12日補

一、新增一級選單:

1、一級選單項的實現是Activity

     實現項是Activity的話比較簡單,如上述HardKey.java,此類檔案直接繼承的是Activity,新增比較簡單

(1)、在清單檔案中新增如下內容    

<activity android:name="HardKey"
                android:label="@string/hardkey_switch"
                android:icon="@drawable/a2_zuo_you_jiaohuan_2"
                android:taskAffinity="">
            <intent-filter android:priority="1">
                <action android:name="com.android.settings.HARDKEY" />
                <action android:name="android.settings.HARDKEY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.VOICE_LAUNCH" />
                <category android:name="com.android.settings.SHORTCUT" />
            </intent-filter>
            <intent-filter android:priority="9">//在category中的物理位置(按優先順序排序時用到,並不是指第9個位置,數越大優先順序越大越靠前)
                <action android:name="com.android.settings.action.SETTINGS" />//指定此項在settings中顯示
            </intent-filter>
            <meta-data android:name="com.android.settings.category"
                android:value="com.android.settings.category.device" />//指定此項顯示在device這一category中
            <meta-data android:name="com.android.settings.ACTIVITY_ACTION" //ACTIVITY_ACTION表明 value指向的類是Activity
                android:value="com.android.settings.HardKey" />
            
            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                android:value="true" />
        </activity>


   (2)、自己實現HardKey這個Activity,其中是按鍵交換功能邏輯的實現

2、一級選單項的實現是fragment

(1)、在清單檔案中新增如下內容 

<activity android:name="Settings$FlashSettingsActivity"   //注意此處,FlashSettingsActivity是Settings的內部類,後面會解釋
                android:label="@string/flash_control_title"
                android:icon="@drawable/a2_hu_xi_deng_2"
                android:taskAffinity="">
            <intent-filter android:priority="1">
                <action android:name="com.android.settings.FLASH_SETTING" />
                <action android:name="android.settings.FLASH_SETTING" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.VOICE_LAUNCH" />
                <category android:name="com.android.settings.SHORTCUT" />
            </intent-filter>
            <intent-filter android:priority="9">
                <action android:name="com.android.settings.action.SETTINGS" />
            </intent-filter>
            <meta-data android:name="com.android.settings.category"
                android:value="com.android.settings.category.device" />
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"//FRAGMENT_CLASS 表明value指定的類是fragment
                android:value="com.android.settings.FlashSettings" /> //FlashSettings實現類
            
            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                android:value="true" />
        </activity>


 (2)、自己實現FlashSettings 這個fragment


 (3)、在Settings.java中新增

 public static class FlashSettingsActivity extends SettingsActivity { /* empty */ }

FlashSettingsActivity 並不是一個Activity檔案,只是一個SettingsActivity的子類,且是空實現。之所以要加此空的Activity,是為了外部應用能直接跳轉到FlashSettingsActivity介面,因為如果只是fragment的話,外部是沒法跳轉到fragment介面的,跳轉到FalshSettingsActivity時,會執行其父類SettingsActivity.java中的方法,並根據FlashSettingsActivity在清單檔案中的註冊資訊, 它的meta-data的值,找到FlashSettingsActivity對應的fragment(FlashSettings),顯示出fragment介面,實現借殼。

如果<meta-data>中使用的是FRAGMENT_CLASS,一般都會宣告成Settings的內部類即 <activity android:name="Settings$xxxActivity" > 的形式。

注意此fragment是繼承與settings中通用的SettingsPreferenceFragment,並不是一般的fragment類

3、一級選單需要跳轉到其他應用

(1)、在清單檔案中新增和Fragment一樣的內容(其實並沒有此fragment的實現類,只為了使用其中的fragment名)

<activity android:name="Settings$ZsSystemUpdateSettingsActivity" //這樣寫,然後在Settings中宣告成Settings的內部類,從而不需要單獨再寫ZsSystemUpdateSettings的實現類
            android:label="@string/system_update_settings_list_item_title" 
            android:icon="@drawable/ic_system_update" 
            android:taskAffinity="com.android.settings"
            android:parentActivityName="Settings">
            <intent-filter android:priority="1">
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.VOICE_LAUNCH" />
            </intent-filter>
            <intent-filter android:priority="-1">
                <action android:name="com.android.settings.action.SETTINGS" />
            </intent-filter>
            <meta-data android:name="com.android.settings.category"
                android:value="com.android.settings.category.system" />
            <meta-data android:name="com.android.settings.title"
                android:resource="@string/system_update_settings_list_item_title" />
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                android:value="android.settings.ZsSystemUpdateSettings" />//ZsSystemUpdateSettings只是個fragment名字
            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                android:value="true" />
        </activity>


  (2)、在Settings中新增public static class  ZsSystemUpdateSettingsActivity extends SettingsActivity { /* empty */ }


  (3)、在SettingsActivity中方法switchToFragment裡面新增如下內容,實現跳轉到三方應用介面

if (“android.settings.ZsSystemUpdateSettings”.equals(fragmentName)) {
            Intent ZsSystemUpdateIntent = new Intent();
            String pakagename="com.yulong.android.ota";
            String classname="com.yulong.android.ota.ui.MainActivity";
            ComponentName component = new ComponentName(pakagename, classname);
            ZsSystemUpdateIntent.setComponent(component);
            startActivity(ZsSystemUpdateIntent);
            finish();
            return null;
        }

二、新增二級選單:

二級選單和6.0沒有區別,這裡不再講解

參考資料