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

相关推荐
大白要努力!1 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee1 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood1 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-4 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen6 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年14 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿16 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神17 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛17 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法18 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526