需求:
在设置中,添加一级菜单项,在设备中加入“按键交换”,此项菜单与“显示”并列
由于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没有区别,这里不再讲解
参考资料
http://blog.csdn.net/wzy_1988/article/details/50556113