Android原生设置Settings 具体Fragment和Activity界面跳转实现
文章目录
- Android原生设置Settings 具体Fragment和Activity界面跳转实现
一、前言
Android 原生设置Settings中如果要跳转到某个界面,如何实现?
从代码上看,只能看到某些Activity的跳转,或者一些主要的Fragment是有暴露的,
而对于多层级的Fragment 没看到有代码有直接暴露的代码。
这种情况,如果要跳转到某个Fragment,要如何实现呢?
其实原生Settings 对这块需求是有设计实现功能的,可以实现跳转到某个未暴露的Fragment 界面,
但是有个限制:跳转未暴露的Fragment 应用需要是系统签名uid=1000d的应用,不然会报错。
对于跳转到具体Fragment和Activity的需求,在实际项目中还是比较实用的,毕竟原生Settings很多功能是其他应用没有实现的。
最初只想介绍一下Fragment跳转的,后面随便看了暴露的Activity界面,也简单写上去了。
如果有需求的可以继续往下看看,Android上层正常开发估计也有比较大作用的,有需求的可以收藏查看。
二、实现跳转到Settings某个界面的代码
1、跳转到某个Settings 应用和某个Fragment 界面示例
//跳转到Settings应用有N种方法,这是其中一个 public void jumpMain(View view) { Intent intent = new Intent(); intent.setAction("android.settings.SETTINGS"); intent.setPackage("com.android.settings"); startActivity(intent); } //跳转到开发组选项界面 public void jumpDeveloper(View view) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.SubSettings")); intent.putExtra(":settings:show_fragment", "com.android.settings.development.DevelopmentSettingsDashboardFragment"); startActivity(intent); }
第二个方法就是跳转到Settings 某个Fragment界面的代码。
2、跳转到某个Settings某个Fragment 界面的封装方法代码
//跳转到开发这选项界面 public void jumpDeveloper(View view) { jumpSettingsFragment("development.DevelopmentSettingsDashboardFragment"); } //跳转到签名证书信息界面 public void jumpSecurity(View view) { jumpSettingsFragment("security.EncryptionAndCredential"); } //其他Settings里面的Fragment 也可以调用这个封装方法 //跳转到某个Fragment的封装方法,只要传入最后的包名和类名 public void jumpSettingsFragment(String fragmentName) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.SubSettings")); intent.putExtra(":settings:show_fragment", "com.android.settings." + fragmentName); startActivity(intent); }
通过封装的方法,传入模块名称和相关Fragment名称就可以显示到具体的界面。
3、其他Fragment界面的信息:
Android 原生设置Settings各个功能模块的代码是分别写在不同的文件的。每个文件夹都是一个功能模块,里面包含一些工具类,Activity 和 Fragment 等界面。
(1)原生Settings外层目录图片:
截图展示不了那么多,上面只是src的部分目录,下面的是详细目录。
(2)Android14 原生Settings文件目录 列表:
release$ cd packages/apps/Settings/src/com/android/settings/ accessibility/ bluetooth/ deletionhelper/ ethernet/ location/ print/ shortcut/ theme/ wfd/ accounts/ bugreporthandler/ development/ flashlight/ media/ privacy/ sim/ tts/ widget/ activityembedding/ communal/ deviceinfo/ fuelgauge/ network/ ramextension/ slices/ users/ wifi/ applications/ connecteddevice/ devicelock/ gestures/ nfc/ regionalpreferences/ sound/ utils/ aware/ core/ display/ homepage/ notification/ safetycenter/ spa/ uwb/ backup/ dashboard/ dream/ inputmethod/ overlay/ screenshot/ support/ vpn2/ biometrics/ datausage/ emergency/ language/ panel/ search/ survey/ wallpaper/ biometrics2/ datetime/ enterprise/ localepicker/ password/ security/ system/ webview/ release$ cd packages/apps/Settings/src/com/android/settings/
应该不是所有的Fragment都可以使用 “:settings:show_fragment” 方式展示,Settings中有些界面是单独的Activity和Fragment。
大部分Fragment界面都是可以使用 ":settings:show_fragment"方式进行跳转,
这些Fragment界面是没有归类的,需要大家在使用过程进行研究使用。
三、其他
1、adb命令 跳转到Settings应用:
//方式1: adb shell am start -a android.settings.SETTINGS //方式2: am start com.android.settings/.Settings //方式3: am start com.android.settings/.SubSettings
其他方式肯定还有的,这里不一一介绍了。
2、使用adb 命令跳转到Settings Fragment 界面无效?
(1)使用“am broadcast”发送广播的命令不行?
C:\Users\As11040>adb shell am broadcast -n com.android.settings/com.android.settings.SubSettings --es ":settings:show_fragment" "com.android.settings.development.DevelopmentSettingsDashboardFragment" Broadcasting: Intent { flg=0x400000 cmp=com.android.settings/.SubSettings (has extras) } Broadcast completed: result=0 C:\Users\As11040>
返回结果是0,发送广播是没人接收。
为啥不行,按道理发送广播就是命令: “am broadcast XXX”
(2)可以使用“am start”的命令
C:\Users\As11040>adb shell am start -n com.android.settings/com.android.settings.SubSettings --es ":settings:show_fragment" "com.android.settings.development.DevelopmentSettingsDashboardFragment" Starting: Intent { cmp=com.android.settings/.SubSettings (has extras) } C:\Users\As11040>
(3)am broadcast 和 am start 简单区别
am broadcast 用于发送广播; am start 用于启动 Activity。 比如自己有监听广播的代码,使用 am broadcast发送广播自己是可以收到的。 拉起界面就要用am start 了。 发送相关数据的参数形式 am broadcast 和 am start 是一样的。
所以说这里拉起应用不是发送广播,必须使用 am start 。
3、跳转到Settings的Fragment权限报错
如果要应用没有权限调用拉起Fragment 界面是会报错的。
(1)报错日志:
普通应用如果执行跳转到某个Fragment 的代码报错如下:
Caused by: java.lang.SecurityException: Permission Denial: starting Intent { cmp=com.android.settings/.SubSettings (has extras) } from ProcessRecord{a3725bd 7723:com.demo.settingsview/u0a96} (pid=7723, uid=10096) not exported from uid 1000 at android.os.Parcel.createExceptionOrNull(Parcel.java:3057) at android.os.Parcel.createException(Parcel.java:3041) at android.os.Parcel.readException(Parcel.java:3024) at android.os.Parcel.readException(Parcel.java:2966) at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:2243) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1873) at android.app.Activity.startActivityForResult(Activity.java:5758) at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676) at android.app.Activity.startActivityForResult(Activity.java:5716) at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663) at android.app.Activity.startActivity(Activity.java:6214) at android.app.Activity.startActivity(Activity.java:6181) at com.demo.settingsview.MainActivity.jumpSettingsFragment(MainActivity.java:54) at com.demo.settingsview.MainActivity.jumpDeveloper(MainActivity.java:32) at java.lang.reflect.Method.invoke(Native Method) at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:397) at android.view.View.performClick(View.java:7668) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:967) at android.view.View.performClickInternal(View.java:7645) at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0) at android.view.View$PerformClick.run(View.java:30179) at android.os.Handler.handleCallback(Handler.java:958) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:205) at android.os.Looper.loop(Looper.java:294) at android.app.ActivityThread.main(ActivityThread.java:8248) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) Caused by: android.os.RemoteException: Remote stack trace: at com.android.server.wm.ActivityTaskSupervisor.checkStartAnyActivityPermission(ActivityTaskSupervisor.java:1136) at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1074) at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:742) at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1300) at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1251)
上面提示了 Permission Denial ,并且 not exported from uid 1000,表示要uid为 1000的情况才能才有权限。
如果adb命令也是同样会报错,除非成功执行了adb root,就有权限拉起 Fragment界面。
(2)报错的代码位置
报错的具体位置很多人可能会以为是在 ActiveServices.java
但是实际是在 ActivityTaskSupervisor.java 里面报错。
framework\base\services\core\java\com\android\server\wm\ActivityTaskSupervisor.java
报错的具体方法:
boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, ...) { ... } else if (!aInfo.exported) { msg = "Permission Denial: starting " + intent.toString() + " from " + callerApp + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " not exported from uid " + aInfo.applicationInfo.uid; } else { ... }
系统中设计是未暴露的组件不能随便被其他应用访问,系统应用不受限制。
这个 Fragment 界面对应的 Activity 确实是 隐藏的。
Settings 的 SubSettings Activity在AndroidManifest.xml中的定义:
<activity android:name=".SubSettings" android:exported="false" android:theme="@style/Theme.SubSettings" />
Android系统对于 exported=“false” 的组件,就是做了限制,没办法直接跳过。
(3)拉起Settings Fragment 界面权限小结 :
1、代码中跳转到Fragment界面就要设置uid权限 2、adb命令跳转到Fragment 就要 root权限 3、还有一种解决方法直接修改Settings应用,把 SubSettings 修改成 android:exported="true" 可以让普通应用直接拉起Fragment界面。
4、Settings中SubSettings的":settings:show_fragment"能使能的原因分析
(1)Intent中读取了是否包含额外参数Extra
//SubSettings没啥实现,主要逻辑在父类中 //要说作用就是控制这个Activity不可见。安全? public class SubSettings extends SettingsActivity { } //show_fragment 的信息读取 public class SettingsActivity extends SettingsBaseActivity { //额外参数Extra public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment"; //其他参数 public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args"; public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"; //读取Extra 判断是哪个Fragment @VisibleForTesting public String getInitialFragmentName(Intent intent) { return intent.getStringExtra(EXTRA_SHOW_FRAGMENT); } //show_fragment最重要使能的原因是Activity onCreate中有读取是否要跳转到某个Fragment @Override protected void onCreate(Bundle savedState) { // Should happen before any call to getIntent() getMetaData(); final Intent intent = getIntent(); super.onCreate(savedState); Log.d(LOG_TAG, "Starting onCreate"); //根据Intent信息,判断是否要跳转到某个Fragment createUiFromIntent(savedState, intent); } ... }
5、拉起Settings 暴露的Activity界面
虽然Settings内部很多Fragment 界面是隐藏的,
但是也有很多暴露的Activity界面,比如主要的,wifi设置、蓝牙设置、关于界面等都是暴露的。
通过查看 AndroidManifest.xml 是可以看到 exported=“true” 暴露的所有Activity界面。
部分界面:
//wifi设置界面 <activity android:name="Settings$WifiSettingsActivity" android:label="@string/wifi_settings" android:icon="@drawable/ic_homepage_network" android:exported="true" android:configChanges="orientation|keyboardHidden|screenSize"> <intent-filter android:priority="1"> //可以使用Action进行跳转 <action android:name="android.settings.WIFI_SETTINGS"/> </intent-filter> </activity> //蓝牙设置界面,没有Acting咋搞? <activity-alias android:name="Settings$BluetoothSettingsActivity" android:label="@string/devices_title" android:targetActivity=".Settings$ConnectedDeviceDashboardActivity" android:exported="true"> <intent-filter android:priority="10"> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.settings.SHORTCUT" /> </intent-filter> </activity-alias> //蓝牙设置界面,可以使用包名跳转 <!-- Keep compatibility with old shortcuts. --> <activity-alias android:name=".bluetooth.BluetoothSettings" android:label="@string/devices_title" android:targetActivity="Settings$BluetoothSettingsActivity" android:exported="true" android:clearTaskOnLaunch="true"> </activity-alias> //p2p设置界面,没有acting咋搞? <activity android:name="Settings$WifiP2pSettingsActivity" android:exported="true"> <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> </activity>
(1) adb 拉起设置界面 命令:
//方式一:使用action C:\Users\As11040>adb shell am start -a android.settings.WIFI_SETTINGS Starting: Intent { act=android.settings.WIFI_SETTINGS } //方式二:包名类名 C:\Users\As11040>adb shell am start -n com.android.settings/.Settings$BluetoothSettingsActivity Starting: Intent { cmp=com.android.settings/.Settings } 第二种方法没啥用啊,只是拉起的Settings的主界面。 //研究了一下发现,linux中$符合要\转义才能识别,所以正确的命令是: C:\Users\As11040>adb shell am start -n com.android.settings/.Settings\$BluetoothSettingsActivity Starting: Intent { cmp=com.android.settings/.Settings$BluetoothSettingsActivity } C:\Users\As11040> 这下就拉起了蓝牙设置界面
(2)Java 拉起设置界面 命令:
//跳转到Settings应用wifi设置界面 public void jumpMain(View view) { Intent intent = new Intent(); //方式1,指定action: //intent.setAction("android.settings.WIFI_SETTINGS"); //方式2:,指定包名和类名,这里内部类$不用转义 intent.setClassName("com.android.settings","com.android.settings.Settings$WifiSettingsActivity"); intent.setPackage("Settings$WifiSettingsActivity"); startActivity(intent); }
(3)Android 暴露的常用界面列表:
Settings\src\com\android\settings\Settings.java
里面有很多内部类的Activity都是暴露的Activity界面。
部分 Activity如下:
public class Settings extends SettingsActivity { public static class MemtagPageActivity extends SettingsActivity { /* empty */} public static class AssistGestureSettingsActivity extends SettingsActivity { /* empty */} public static class BluetoothSettingsActivity extends SettingsActivity { /* empty */ } public static class CreateShortcutActivity extends SettingsActivity { /* empty */ } public static class FaceSettingsActivity extends SettingsActivity { @Override protected void onCreate(Bundle savedState) { setTheme(SetupWizardUtils.getTheme(this, getIntent())); setTheme(R.style.SettingsPreferenceTheme_SetupWizard); ThemeHelper.trySetDynamicColor(this); super.onCreate(savedState); } } ... public static class VpnSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for Data saver settings. */ public static class DataSaverSummaryActivity extends SettingsActivity { /* empty */ } public static class DateTimeSettingsActivity extends SettingsActivity { /* empty */ } public static class PrivateVolumeForgetActivity extends SettingsActivity { /* empty */ } public static class PublicVolumeSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiSettingsActivity extends SettingsActivity { /* empty */ } public static class NetworkProviderSettingsActivity extends SettingsActivity { /* empty */ } public static class NetworkSelectActivity extends SettingsActivity { /* empty */ } /** Activity for the Wi-Fi network details settings. */ public static class WifiDetailsSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiP2pSettingsActivity extends SettingsActivity { /* empty */ } public static class AvailableVirtualKeyboardActivity extends SettingsActivity { /* empty */ } public static class KeyboardLayoutPickerActivity extends SettingsActivity { /* empty */ } public static class PhysicalKeyboardActivity extends SettingsActivity { /* empty */ } public static class InputMethodAndSubtypeEnablerActivity extends SettingsActivity { /* empty */ } public static class SpellCheckersSettingsActivity extends SettingsActivity { /* empty */ } public static class LocalePickerActivity extends SettingsActivity { /* empty */ } public static class LanguageAndInputSettingsActivity extends SettingsActivity { /* empty */ } public static class LanguageSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for the regional preferences settings. */ public static class RegionalPreferencesActivity extends SettingsActivity { /* empty */ } public static class KeyboardSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for the navigation mode settings. */ public static class NavigationModeSettingsActivity extends SettingsActivity { /* empty */ } public static class UserDictionarySettingsActivity extends SettingsActivity { /* empty */ } public static class DarkThemeSettingsActivity extends SettingsActivity { /* empty */ } public static class DisplaySettingsActivity extends SettingsActivity { /* empty */ } public static class NightDisplaySettingsActivity extends SettingsActivity { /* empty */ } public static class NightDisplaySuggestionActivity extends NightDisplaySettingsActivity { /* empty */ } public static class SmartAutoRotateSettingsActivity extends SettingsActivity { /* empty */ } public static class MyDeviceInfoActivity extends SettingsActivity { /* empty */ } public static class ModuleLicensesActivity extends SettingsActivity { /* empty */ } public static class ApplicationSettingsActivity extends SettingsActivity { /* empty */ } public static class ManageApplicationsActivity extends SettingsActivity { /* empty */ } public static class ManageAssistActivity extends SettingsActivity { /* empty */ } public static class HighPowerApplicationsActivity extends SettingsActivity { /* empty */ } public static class BackgroundCheckSummaryActivity extends SettingsActivity { /* empty */ } public static class StorageUseActivity extends SettingsActivity { /* empty */ } public static class DevelopmentSettingsDashboardActivity extends SettingsActivity { /* empty */ } public static class AccessibilitySettingsActivity extends SettingsActivity { /* empty */ } public static class AccessibilityDetailsSettingsActivity extends SettingsActivity { /* empty */ } public static class CaptioningSettingsActivity extends SettingsActivity { /* empty */ } public static class AccessibilityInversionSettingsActivity extends SettingsActivity { /* empty */ } public static class AccessibilityContrastSettingsActivity extends SettingsActivity { /* empty */ } public static class AccessibilityDaltonizerSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for lockscreen settings. */ public static class LockScreenSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for bluetooth pairing settings. */ public static class BlueToothPairingActivity extends SettingsActivity { /* empty */ } /** Activity for Reduce Bright Colors. */ public static class ReduceBrightColorsSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for text reading settings. */ public static class TextReadingSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for text color and motion settings. */ public static class ColorAndMotionActivity extends SettingsActivity { /* empty */ } /** Activity for the security dashboard. */ public static class SecurityDashboardActivity extends SettingsActivity {...} /** Activity for the More settings page. */ public static class MoreSecurityPrivacySettingsActivity extends SettingsActivity { /* empty */ } public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ } public static class AppUsageAccessSettingsActivity extends SettingsActivity { /* empty */ } public static class LocationSettingsActivity extends SettingsActivity { /* empty */ } public static class ScanningSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiScanningSettingsActivity extends SettingsActivity { /* empty */ } /** Activity for the privacy dashboard. */ public static class PrivacyDashboardActivity extends SettingsActivity { private static final String TAG = "PrivacyDashboardActivity"; @Override protected void onCreate(Bundle savedState) { super.onCreate(savedState); handleSafetyCenterRedirection(); } /** Redirects to SafetyCenter if enabled. */ @VisibleForTesting public void handleSafetyCenterRedirection() { if (isFinishing()) { // Don't trampoline if already exiting this activity. return; } if (ACTION_PRIVACY_SETTINGS.equals(getIntent().getAction()) && SafetyCenterManagerWrapper.get().isEnabled(this)) { try { startActivity(new Intent(Intent.ACTION_SAFETY_CENTER)); finish(); } catch (ActivityNotFoundException e) { Log.e(TAG, "Unable to open safety center", e); } } } } public static class PrivacyControlsActivity extends SettingsActivity { /* empty */ } public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ } public static class FactoryResetActivity extends SettingsActivity { @Override protected void onCreate(Bundle savedState) { setTheme(SetupWizardUtils.getTheme(this, getIntent())); ThemeHelper.trySetDynamicColor(this); super.onCreate(savedState); } @Override protected boolean isToolbarEnabled() { return false; } } public static class FactoryResetConfirmActivity extends SettingsActivity { @Override protected void onCreate(Bundle savedState) { setTheme(SetupWizardUtils.getTheme(this, getIntent())); ThemeHelper.trySetDynamicColor(this); super.onCreate(savedState); } @Override protected boolean isToolbarEnabled() { return false; } } public static class RunningServicesActivity extends SettingsActivity { /* empty */ } public static class BatterySaverSettingsActivity extends SettingsActivity { /* empty */ } public static class BatterySaverScheduleSettingsActivity extends SettingsActivity { /* empty */ } public static class AccountSyncSettingsActivity extends SettingsActivity { /* empty */ } public static class AccountSyncSettingsInAddAccountActivity extends SettingsActivity { /* empty */ } public static class DeviceAdminSettingsActivity extends SettingsActivity { /* empty */ } public static class DataUsageSummaryActivity extends SettingsActivity { /* empty */ } public static class MobileDataUsageListActivity extends SettingsActivity { /* empty */ } public static class ConfigureWifiSettingsActivity extends SettingsActivity { /* empty */ } public static class SavedAccessPointsSettingsActivity extends SettingsActivity { /* empty */ } public static class TextToSpeechSettingsActivity extends SettingsActivity { /* empty */ } public static class AndroidBeamSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiDisplaySettingsActivity extends SettingsActivity { /* empty */ } public static class DreamSettingsActivity extends SettingsActivity { /* empty */ } /** Activity to manage communal settings */ public static class CommunalSettingsActivity extends SettingsActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!CommunalPreferenceController.isAvailable(this)) { finish(); } } } public static class NotificationStationActivity extends SettingsActivity { /* empty */ } public static class UserSettingsActivity extends SettingsActivity { /* empty */ } public static class NotificationAccessSettingsActivity extends SettingsActivity { /* empty */ } public static class NotificationAccessDetailsActivity extends SettingsActivity { /* empty */ } public static class VrListenersSettingsActivity extends SettingsActivity { /* empty */ } public static class PremiumSmsAccessActivity extends SettingsActivity { /* empty */ } public static class PictureInPictureSettingsActivity extends SettingsActivity { /* empty */ } public static class TurnScreenOnSettingsActivity extends SettingsActivity { /* empty */ } public static class AppTurnScreenOnSettingsActivity extends SettingsActivity { /* empty */ } public static class AppPictureInPictureSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenAccessSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenAccessDetailSettingsActivity extends SettingsActivity {} public static class ConditionProviderSettingsActivity extends SettingsActivity { /* empty */ } public static class UsbSettingsActivity extends SettingsActivity { /* empty */ } public static class UsbDetailsActivity extends SettingsActivity { /* empty */ } public static class TrustedCredentialsSettingsActivity extends SettingsActivity { /* empty */ } public static class PaymentSettingsActivity extends SettingsActivity { /* empty */ } public static class PrintSettingsActivity extends SettingsActivity { /* empty */ } public static class PrintJobSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenModeSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenModeBehaviorSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenModeBlockedEffectsSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenModeAutomationSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenModeScheduleRuleSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenModeEventRuleSettingsActivity extends SettingsActivity { /* empty */ } public static class SoundSettingsActivity extends SettingsActivity { /* empty */ } public static class ConfigureNotificationSettingsActivity extends SettingsActivity { /* empty */ } public static class ConversationListSettingsActivity extends SettingsActivity { /* empty */ } public static class AppBubbleNotificationSettingsActivity extends SettingsActivity { /* empty */ } public static class NotificationAssistantSettingsActivity extends SettingsActivity{ /* empty */ } public static class NotificationAppListActivity extends SettingsActivity { /* empty */ } /** Activity to manage Cloned Apps page */ public static class ClonedAppsListActivity extends SettingsActivity { /* empty */ } public static class NotificationReviewPermissionsActivity extends SettingsActivity { /* empty */ } public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ } public static class ChannelNotificationSettingsActivity extends SettingsActivity { /* empty */ } public static class ChannelGroupNotificationSettingsActivity extends SettingsActivity { /* empty */ } public static class ManageDomainUrlsActivity extends SettingsActivity { /* empty */ } public static class AutomaticStorageManagerSettingsActivity extends SettingsActivity { /* empty */ } public static class GamesStorageActivity extends SettingsActivity { /* empty */ } public static class GestureNavigationSettingsActivity extends SettingsActivity { /* empty */ } /** Activity to manage 2-/3-button navigation configuration. */ public static class ButtonNavigationSettingsActivity extends SettingsActivity { /* empty */ } public static class InteractAcrossProfilesSettingsActivity extends SettingsActivity { /* empty */ } public static class AppInteractAcrossProfilesSettingsActivity extends SettingsActivity { /* empty */ } public static class ApnSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiCallingSettingsActivity extends SettingsActivity { /* empty */ } public static class MemorySettingsActivity extends SettingsActivity { /* empty */ } public static class AppMemoryUsageActivity extends SettingsActivity { /* empty */ } public static class OverlaySettingsActivity extends SettingsActivity { /* empty */ } public static class ManageExternalStorageActivity extends SettingsActivity { /* empty */ } public static class AppManageExternalStorageActivity extends SettingsActivity { /* empty */ } public static class MediaManagementAppsActivity extends SettingsActivity { /* empty */ } public static class AppMediaManagementAppsActivity extends SettingsActivity { /* empty */ } public static class WriteSettingsActivity extends SettingsActivity { /* empty */ } public static class ChangeWifiStateActivity extends SettingsActivity { /* empty */ } /** Activity to manage NFC Tag applications. */ public static class ChangeNfcTagAppsActivity extends SettingsActivity { /* empty */ } public static class AppDrawOverlaySettingsActivity extends SettingsActivity { /* empty */ } public static class AppWriteSettingsActivity extends SettingsActivity { /* empty */ } /** Activity to manage app battery usage details. */ public static class AppBatteryUsageActivity extends SettingsActivity { /* empty */ } public static class ManageExternalSourcesActivity extends SettingsActivity {/* empty */ } public static class ManageAppExternalSourcesActivity extends SettingsActivity { /* empty */ } public static class WallpaperSettingsActivity extends SettingsActivity { /* empty */ } public static class ManagedProfileSettingsActivity extends SettingsActivity { /* empty */ } public static class DeletionHelperActivity extends SettingsActivity { /* empty */ } /** Actviity to manage apps with {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM} */ public static class AlarmsAndRemindersActivity extends SettingsActivity {/* empty */ } /** App specific version of {@link AlarmsAndRemindersActivity} */ public static class AlarmsAndRemindersAppActivity extends SettingsActivity {/* empty */ } public static class ApnEditorActivity extends SettingsActivity { /* empty */ } public static class ChooseAccountActivity extends SettingsActivity { /* empty */ } public static class IccLockSettingsActivity extends SettingsActivity { /* empty */ } public static class TestingSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiAPITestActivity extends SettingsActivity { /* empty */ } public static class WifiInfoActivity extends SettingsActivity { /* empty */ } public static class EnterprisePrivacySettingsActivity extends SettingsActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (FeatureFactory.getFactory(this) .getEnterprisePrivacyFeatureProvider(this) .showParentalControls()) { finish(); } else if (!EnterprisePrivacySettings.isPageEnabled(this)) { finish(); } } } public static class WebViewAppPickerActivity extends SettingsActivity { /* empty */ } public static class AdvancedConnectedDeviceActivity extends SettingsActivity { /* empty */ } public static class NfcSettingsActivity extends SettingsActivity { /* empty */ } public static class BluetoothDeviceDetailActivity extends SettingsActivity { /* empty */ } public static class StylusUsiDetailsActivity extends SettingsActivity { /* empty */ } public static class BluetoothBroadcastActivity extends SettingsActivity { /* empty */ } public static class BluetoothFindBroadcastsActivity extends SettingsActivity { /* empty */ } public static class WifiCallingDisclaimerActivity extends SettingsActivity { /* empty */ } public static class MobileNetworkListActivity extends SettingsActivity {} public static class PowerMenuSettingsActivity extends SettingsActivity {} public static class MobileNetworkActivity extends SettingsActivity { public static final String TAG = "MobileNetworkActivity"; public static final String EXTRA_MMS_MESSAGE = "mms_message"; public static final String EXTRA_SHOW_CAPABILITY_DISCOVERY_OPT_IN = "show_capability_discovery_opt_in"; private MobileNetworkIntentConverter mIntentConverter; /** * Override of #onNewIntent() requires Activity to have "singleTop" launch mode within * AndroidManifest.xml */ @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.d(TAG, "Starting onNewIntent"); createUiFromIntent(null /* savedState */, convertIntent(intent)); } @Override public Intent getIntent() { return convertIntent(super.getIntent()); } private Intent convertIntent(Intent copyFrom) { if (mIntentConverter == null) { mIntentConverter = new MobileNetworkIntentConverter(this); } Intent intent = mIntentConverter.apply(copyFrom); return (intent == null) ? copyFrom : intent; } public static boolean doesIntentContainOptInAction(Intent intent) { String intentAction = (intent != null ? intent.getAction() : null); return TextUtils.equals(intentAction, ImsRcsManager.ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN); } } /** Actviity to manage apps with {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} */ public static class LongBackgroundTasksActivity extends SettingsActivity { /* empty */ } /** App specific version of {@link LongBackgroundTasksActivity} */ public static class LongBackgroundTasksAppActivity extends SettingsActivity { /* empty */ } /** * Activity for BugReportHandlerPicker. */ public static class BugReportHandlerPickerActivity extends SettingsActivity { /* empty */ } // Top level categories for new IA public static class NetworkDashboardActivity extends SettingsActivity {} public static class ConnectedDeviceDashboardActivity extends SettingsActivity {} public static class PowerUsageSummaryActivity extends SettingsActivity { /* empty */ } public static class StorageDashboardActivity extends SettingsActivity {} public static class AccountDashboardActivity extends SettingsActivity {} public static class SystemDashboardActivity extends SettingsActivity {} /** * Activity for MediaControlsSettings */ public static class MediaControlsSettingsActivity extends SettingsActivity {} /** * Activity for AppDashboard. */ public static class AppDashboardActivity extends SettingsActivity {} public static class AdaptiveBrightnessActivity extends SettingsActivity { /* empty */ } /** * Activity for OneHandedSettings */ public static class OneHandedSettingsActivity extends SettingsActivity { /* empty */ } }
上面这些Activity 都是Settings的内部类,是暴露的Activity,根据命名大概可以猜测到界面的作用,
上面这些Activity可以通过代码或者adb命令拉起。
Settings中也有部分Activity不是Settings的内部类,需要查看AndroidManifest.xml 是否包含exported=“true”,看该Activity是不是暴露的。
6、拉起Settings界面小结
(1)拉起Settings某个Fragment界面
SubSettings默认是隐藏的,所以需要系统uid权限,adb拉起要root权限,或者修改Settings设置 exported=“true”。
虽然拉起Settings某个Fragment界面不太常用,但是对于某些要求比较具体功能界面的需求还是有用的。比较不友好的就是需要系统权限。
(2)拉起Settings某个Activity界面
可以在AndroidManifest.xml中查看存在的Activity界面
查看到 exported=“true” 就是暴露的Activity界面
其中Settings$XXActvity ,是内部类的Activity,也是可以用代码或者adb 拉起的。
拉起Activity,这个确实比较常用并且不用权限,缺点就是只能拉起比较外部的界面,
部分Activity也是通过额外参数控制进入某个Fragment界面的,需要查看实际代码才知道。
7、Android adb命令发送广播介绍
adb shell am broadcast 详解
https://blog.csdn.net/wenzhi20102321/article/details/136895508