1.创建一级菜单
packages\apps\Settings\res\xml\top_level_settings.xml
<com.android.settings.widget.HomepagePreference
android:fragment="com.android.settings.DeviceStatusSettings"
android:icon="@drawable/ic_settings_display_white"
android:key="top_level_device_status"
android:order="-80"
android:title="@string/device_status_settings"
android:summary="@string/device_status_dashboard_summary"
settings:controller="com.android.settings.devicestatus.TopLevelDeviceStatusPreferenceController"/>
DeviceStatusSettings
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class DeviceStatusSettings extends DashboardFragment {
private static final String TAG = "DeviceStatusSettings";
private static final String KET_SPK_MODE_SETTINGS = "spk_mode_settings";
@Override
public int getMetricsCategory() {
return SettingsEnums.DISPLAY;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.device_status_setting;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle());
}
@Override
public int getHelpResource() {
return R.string.help_uri_display;
}
private static List<AbstractPreferenceController> buildPreferenceControllers(
Context context, Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new SpkModePreferenceController(context, KET_SPK_MODE_SETTINGS));
return controllers;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.device_status_setting) {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
};
}
TopLevelDeviceStatusPreferenceController
public class TopLevelDeviceStatusPreferenceController extends BasePreferenceController {
public TopLevelDeviceStatusPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
}
2.创建二级菜单
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="display_settings_screen"
android:title="@string/device_status_settings"
settings:keywords="@string/keywords_display">
<PreferenceCategory
android:title="@string/device_spk_mode">
<com.android.settingslib.RestrictedPreference
android:key="device_spk_mode"
android:title="@string/device_spk_mode"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.devicestatus.SpkModeSettings"
settings:controller="com.android.settings.devicestatus.SpkModePreferenceController"/>
</PreferenceCategory>
</PreferenceScreen>
SpkModeSettings
public class SpkModeSettings extends RadioButtonPickerFragment {
private static final String TAG = "SpkModeSettings";
public static final int FALLBACK_VALUE = 0;
private static final String SPK_MODE_BROADCAST = "android.intent.action.SPK_MODE";
private static final String SPK_MODE_PERSIST = "persist.realbom.spkmode";
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
protected List<? extends CandidateInfo> getCandidates() {
final String[] entries = entries();
final String[] values = keys();
final List<SpkModeControlCandidateInfo> candidates = new ArrayList<>();
if (entries == null || entries.length <= 0) return null;
if (values == null || values.length != entries.length) {
throw new IllegalArgumentException("Entries and values must be of the same length.");
}
for (int i = 0; i < entries.length; i++) {
candidates.add(new SpkModeControlCandidateInfo(entries[i], values[i]));
}
return candidates;
}
private String[] entries() {
return getResources().getStringArray(R.array.spk_mode_entries);
}
private String[] keys() {
return getResources().getStringArray(R.array.spk_mode_values);
}
@Override
protected String getDefaultKey() {
return getCurrentSkpModeValue(getContext());
}
@Override
protected boolean setDefaultKey(String key) {
setCurrentSkpModeValue(getContext(), key);
return true;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.spk_mode;
}
@Override
public int getMetricsCategory() {
return 1;
}
private String getCurrentSkpModeValue(Context context) {
if (context == null) {
return Long.toString(FALLBACK_VALUE);
} else {
return SystemProperties.get(SPK_MODE_PERSIST, "0");
}
}
private void setCurrentSkpModeValue(Context context, String key) {
try {
if (context != null) {
Log.d(TAG,"set current value == "+key);
int value = Integer.parseInt((String) key);
SystemProperties.set(SPK_MODE_PERSIST, String.valueOf(value));
//Settings.System.putInt(context.getContentResolver(), SPK_MODE, value);
setSkpModeValue(context,value);
}
} catch (NumberFormatException e) {
Log.e(TAG, "could not persist screen timeout setting", e);
}
}
@Override
protected void onSelectionPerformed(boolean success) {
super.onSelectionPerformed(success);
//getActivity().finish();
}
private final class SpkModeControlCandidateInfo extends CandidateInfo {
private final String name;
private final String key;
SpkModeControlCandidateInfo(String title, String value) {
super(true);
name = title;
key = value;
}
@Override
public CharSequence loadLabel() {
return name;
}
@Override
public Drawable loadIcon() {
return null;
}
@Override
public String getKey() {
return key;
}
}
private void setSkpModeValue(Context context, int value){
Intent intent = new Intent();
intent.setAction(SPK_MODE_BROADCAST);
//intent.putExtra("com",4);
intent.putExtra("value",value);
context.sendBroadcast(intent);
}
}
SpkModePreferenceController
public class SpkModePreferenceController extends BasePreferenceController {
public static String PREF_NAME = "spk_mode";
public static String TAG = "SpkModePreferenceController";
public static final int FALLBACK_VALUE = 0;
private final CharSequence[] mEntries;
private final CharSequence[] mValues;
private static final String SPK_MODE_BROADCAST = "android.intent.action.SPK_MODE";
private static final String SPK_MODE_PERSIST = "persist.realbom.spkmode";
public SpkModePreferenceController(Context context, String key) {
super(context, key);
mEntries = context.getResources().getStringArray(R.array.spk_mode_entries);
mValues = context.getResources().getStringArray(R.array.spk_mode_values);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public void updateState(Preference preference) {
final long curValue = Long.valueOf(SystemProperties.get(SPK_MODE_PERSIST,"0"));
updatePreferenceDescription(preference, curValue);
Log.d(TAG, "updateState currentValue= "+String.valueOf(curValue));
}
public static CharSequence getDescription(long curValue, CharSequence[] entries, CharSequence[] values) {
if (curValue < 0 || entries == null || values == null || values.length != entries.length) {
return null;
}
for (int i = 0; i < values.length; i++) {
long temp = Long.parseLong(values[i].toString());
if (curValue == temp) {
Log.d(TAG,"Description entries == "+entries[i]);
return entries[i];
}
}
return null;
}
private void updatePreferenceDescription(Preference preference,long curValue) {
final CharSequence summary;
summary = getDescription(curValue, mEntries, mValues);
preference.setSummary(summary);
}
}
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/device_spk_mode"/>