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

相关推荐
Kapaseker3 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴3 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭13 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab14 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe19 小时前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋1 天前
Android 协程时代,Handler 应该退休了吗?
android
火柴就是我2 天前
让我们实现一个更好看的内部阴影按钮
android·flutter