根据需求,删除设置界面 部分菜单选项
文章目录
场景
- 前面做了壁纸软件开发,为了不和系统设置壁纸冲突,不让用户去设置里面去设置壁纸,那么需要把壁纸修改选项去掉。 隐藏: 设置->壁纸
- 车载中控产品,好多用的是系统原生设置,大部分会对原生设置进行新增和删除菜单,规避客户误操作
以设置里面去掉壁纸菜单为例,如下:
参考资料
Android 静态壁纸设置实现方案
Settings源码分析1:
Android 11 Settings源码入门
Android Settings和SettingsProvider源码分析与修改
分析Android 11.0Settings源码之主界面加载
[Android 系统应用之Settings(https://juejin.cn/post/7460118583378673714)
实现方案 - 修改文件
这里就以屏蔽壁纸菜单为例
修改文件如下:
/vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/top_level_settings.xml
如果要屏蔽壁纸菜单,那么在布局top_level_settings.xml 中屏蔽如下如选项
源码分析
主界面 Settings
看程序入口配置配置
<!-- Alias for launcher activity only, as this belongs to each profile. -->
<activity-alias android:name="Settings"
android:label="@string/settings_label_launcher"
android:taskAffinity="com.android.settings.root"
android:launchMode="singleTask"
android:exported="true"
android:targetActivity=".homepage.SettingsHomepageActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
</activity-alias>
看这个配置,那么Settings 只是一个别名,真正的启动Activity 为:SettingsHomepageActivity
主界面 SettingsHomepageActivity
主界面 结构如下,从结构上看,这个Activity相当简单,由很多fragment 嵌套完成的。
布局文件 settings_homepage_container
设置布局地方如下
setContentView(R.layout.settings_homepage_container);
两个菜单项,继续看Activity 中加载地方
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_homepage_container);
。。。。。。。。。。
if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
// Only allow features on high ram devices.
final ImageView avatarView = findViewById(R.id.account_avatar);
if (AvatarViewMixin.isAvatarSupported(this)) {
avatarView.setVisibility(View.VISIBLE);
getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
}
showSuggestionFragment();
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
showFragment(new ContextualCardsFragment(), R.id.contextual_cards_content);
}
}
showFragment(new TopLevelSettings(), R.id.main_content);
((FrameLayout) findViewById(R.id.main_content))
.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
}
这里暂时不分析 ContextualCardsFragment TopLevelSettings 的区别
这里可以看到 一级菜单大概率是 TopLevelSettings
一级菜单界面 TopLevelSettings
其实也很简单,这里可以看到加载界面配置文件 top_level_settings
一级菜单配置文件 top_level_settings
源码如下,有好多个 Preference 配置组成,去掉自己想要隐藏的配置即可满足要求
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="top_level_settings">
<Preference
android:fragment="com.android.settings.network.NetworkDashboardFragment"
android:icon="@drawable/ic_settings_wireless"
android:key="top_level_network"
android:order="-150"
android:title="@string/network_dashboard_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.network.TopLevelNetworkEntryPreferenceController"/>
<Preference
android:fragment="com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment"
android:icon="@drawable/ic_devices_other"
android:key="top_level_connected_devices"
android:order="-140"
android:title="@string/connected_devices_dashboard_title"
android:summary="@string/connected_devices_dashboard_default_summary"
settings:controller="com.android.settings.connecteddevice.TopLevelConnectedDevicesPreferenceController"/>
<Preference
android:fragment="com.android.settings.applications.AppDashboardFragment"
android:icon="@drawable/ic_apps"
android:key="top_level_apps"
android:order="-130"
android:title="@string/apps_dashboard_title"
android:summary="@string/app_and_notification_dashboard_summary"/>
<Preference
android:fragment="com.android.settings.notification.ConfigureNotificationSettings"
android:icon="@drawable/ic_notifications"
android:key="top_level_notification"
android:order="-120"
android:title="@string/configure_notification_settings"
android:summary="@string/notification_dashboard_summary"/>
<!--Preference
android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
android:icon="@drawable/ic_settings_battery_white"
android:key="top_level_battery"
android:order="-110"
android:title="@string/power_usage_summary_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.fuelgauge.TopLevelBatteryPreferenceController"/-->
<Preference
android:fragment="com.android.settings.deviceinfo.StorageDashboardFragment"
android:icon="@drawable/ic_storage_white"
android:key="top_level_storage"
android:order="-100"
android:title="@string/storage_settings"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.deviceinfo.TopLevelStoragePreferenceController"/>
<Preference
android:fragment="com.android.settings.notification.SoundSettings"
android:icon="@drawable/ic_volume_up_24dp"
android:key="top_level_sound"
android:order="-90"
android:title="@string/sound_settings"
android:summary="@string/sound_dashboard_summary"/>
<Preference
android:fragment="com.android.settings.DisplaySettings"
android:icon="@drawable/ic_settings_display_white"
android:key="top_level_display"
android:order="-80"
android:title="@string/display_settings"
android:summary="@string/display_dashboard_summary"
settings:controller="com.android.settings.display.TopLevelDisplayPreferenceController"/>
<com.android.settingslib.RestrictedTopLevelPreference
android:icon="@drawable/ic_settings_wallpaper_white"
android:key="top_level_wallpaper"
android:order="-70"
android:title="@string/wallpaper_settings_title"
android:summary="@string/wallpaper_dashboard_summary"
settings:controller="com.android.settings.display.TopLevelWallpaperPreferenceController"/>
<Preference
android:fragment="com.android.settings.accessibility.AccessibilitySettings"
android:icon="@drawable/ic_settings_accessibility"
android:key="top_level_accessibility"
android:order="-60"
android:title="@string/accessibility_settings"
android:summary="@string/accessibility_settings_summary"
settings:controller="com.android.settings.accessibility.TopLevelAccessibilityPreferenceController"/>
<Preference
android:fragment="com.android.settings.security.SecuritySettings"
android:icon="@drawable/ic_settings_security_white"
android:key="top_level_security"
android:order="-50"
android:title="@string/security_settings_title"
android:summary="@string/security_dashboard_summary"
settings:controller="com.android.settings.security.TopLevelSecurityEntryPreferenceController"/>
<Preference
android:fragment="com.android.settings.privacy.PrivacyDashboardFragment"
android:icon="@drawable/ic_settings_privacy"
android:key="top_level_privacy"
android:order="-40"
android:title="@string/privacy_dashboard_title"
android:summary="@string/privacy_dashboard_summary"/>
<Preference
android:fragment="com.android.settings.location.LocationSettings"
android:icon="@drawable/ic_settings_location"
android:key="top_level_location"
android:order="-30"
android:title="@string/location_settings_title"
android:summary="@string/location_settings_loading_app_permission_stats"
settings:controller="com.android.settings.location.TopLevelLocationPreferenceController"/>
<Preference
android:key="top_level_emergency"
android:title="@string/emergency_settings_preference_title"
android:summary="@string/emergency_dashboard_summary"
android:icon="@drawable/ic_settings_emergency"
android:order="-20"
android:fragment="com.android.settings.emergency.EmergencyDashboardFragment"/>
<Preference
android:fragment="com.android.settings.accounts.AccountDashboardFragment"
android:icon="@drawable/ic_settings_accounts"
android:key="top_level_accounts"
android:order="-10"
android:title="@string/account_dashboard_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.accounts.TopLevelAccountEntryPreferenceController"/>
<Preference
android:fragment="com.android.settings.system.SystemDashboardFragment"
android:icon="@drawable/ic_settings_system_dashboard_white"
android:key="top_level_system"
android:order="10"
android:title="@string/header_category_system"
android:summary="@string/system_dashboard_summary"/>
<Preference
android:fragment="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment"
android:icon="@drawable/ic_phone_info"
android:key="top_level_about_device"
android:order="20"
android:title="@string/about_settings"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.deviceinfo.aboutphone.TopLevelAboutDevicePreferenceController"/>
<Preference
android:icon="@drawable/ic_help"
android:key="top_level_support"
android:order="100"
android:title="@string/page_tab_title_support"
android:summary="@string/support_summary"
settings:controller="com.android.settings.support.SupportPreferenceController"/>
</PreferenceScreen>
反思
我们改过很多菜单屏蔽、影藏的需求,那为什么屏蔽了 Preference 选项就能修改成功呢? 曾经有两位同事都问过同一个问题,既然 .xml 属于配置文件,直接屏蔽不会崩溃吗?
这里需要重点理解下 PreferenceScreen 的相关知识了 , 研究系统设置绕不开它的
深入理解Android PreferenceScreen的使用与自定义
android开发之PreferenceScreen使用详解
总结
- 实现屏蔽系统设置中壁纸菜单的需求,了解系统设置一级菜单的加载显示原理
- 这里设计到的相关内容也是设置里面需要重点掌握的基础知识