Android 拉起开发者设置界面命令和代码实现

Android 拉起开发者设置界面命令和代码实现

一、前言

本文记录点简单的知识。

Android进入Android开发者选项,一般步骤是:

1、原生设置--》关于--》点击七次“版本号”条目 (会提示:已打开开发者选项)
2、返回主界面--》系统设置--》开发者设置界面

有些情况,原生设置是隐藏的或者不想打开原生设置,如何直接拉起开发者选项呢?

是否有命令或者代码可以实现呢?

下面简单介绍一下。

二、拉起开发者设置界面实现

1、cmd或者串口拉起开发者设置

//(1)打开开发者选项开关:
settings put global development_settings_enabled 1 

//(2)am通过action或者fragment拉起开发者设置界面
am start -a android.settings.APPLICATION_DEVELOPMENT_SETTINGS
am start -a com.android.settings.APPLICATION_DEVELOPMENT_SETTINGS

am start -n com.android.settings/com.android.settings.SubSettings --es ":settings:show_fragment"  "com.android.settings.development.DevelopmentSettingsDashboardFragment"

//不知道为啥无法启动到这个Activity,查看AndroidManifest 明明是暴露的!
 am start -n com.android.settings/.Settings\$DevelopmentSettingsDashboardActivity

2、代码中拉起开发者设置

(1)设置属性:
import android.provider.Settings;
Settings.Global.putInt(mContext.getContentResolver(), "development_settings_enabled", 1);

(2)发送广播拉起界面
Intent intent = new Intent();
intent.setAction("android.settings.APPLICATION_DEVELOPMENT_SETTINGS");
sendBroadcast(intent);

Settings 属性值默认是记忆的,所以重启设备,开发者选项开关依然也是打开的;

如果没有开启开发者设置开关,直接发广播是无法拉起开发者设置界面的,

会有Toast提示:

   <!-- [CHAR LIMIT=NONE] Toast message when user attemps to launch developer otions before enabling it. -->
    <string name="dev_settings_disabled_warning">Please enable developer options first.</string>

上面注释也写了,如果没有开启开关,就想进入开发者界面就会有下面Toast提示。

为啥会这样,下面会简单说一下。

三、其他

1、拉起开发者设置界面实现小结

可以通过adb或者代码方式拉起开发者设置界面;

要进入开发者设置界面,必须要先打开开发者选项开关;

2、原生Settings中 开发者设置界面定义在AndroidManifest.xml的研究

一般我们看Settings 有啥暴露界面,看 AndroidManifest.xml中的 暴露Activity 就可以。

通过DevelopmentSetting 可以搜索到下面Activity

    <activity
        android:name="Settings$DevelopmentSettingsDashboardActivity"
        android:exported="true"
        android:enabled="false">
        <intent-filter android:priority="1">
            <action android:name="android.settings.APPLICATION_DEVELOPMENT_SETTINGS" />
            <action android:name="com.android.settings.APPLICATION_DEVELOPMENT_SETTINGS" />
        </intent-filter>
...
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                       android:value="com.android.settings.development.DevelopmentSettingsDashboardFragment" />
        </activity>

可以看到上面这个Activity 是暴露的,并且有提供action跳转,

后面还有一个管理数据 Fragment,应该就是具体显示这个Activity的显示界面。

所以得出了上面可以跳转到开发者设置界面的命令。

但是为啥这个 DevelopmentSettingsDashboardActivity 无法实现跳转也是我比较疑惑的。

console:/ # am start -n com.android.settings/.Settings\$DevelopmentSettingsDashboardActivity
Starting: Intent { cmp=com.android.settings/.Settings$DevelopmentSettingsDashboardActivity }
Error type 3
Error: Activity class {com.android.settings/com.android.settings.Settings$DevelopmentSettingsDashboardActivity} does not exist.
console:/ # 

因为我看蓝牙设置界面也是在AndroidManifest中差不多的样子定义的,但是可以跳转。

        <activity-alias //别名
            android:name="Settings$BluetoothSettingsActivity"
            android:targetActivity=".Settings$ConnectedDeviceDashboardActivity" //重定向
            android:exported="true">
        </activity-alias>

        <activity
            android:name=".Settings$ConnectedDeviceDashboardActivity"
            android:exported="true">
                <action android:name="android.settings.BLUETOOTH_SETTINGS" />
  ...
        </activity>

蓝牙设置界面的跳转命令:

//跳转到蓝牙设置界面的两种方式:
console:/ # am start -n com.android.settings/.Settings\$BluetoothSettingsActivity
Starting: Intent { cmp=com.android.settings/.Settings$BluetoothSettingsActivity }
console:/ #

console:/ #
am start -n com.android.settings/.Settings\$ConnectedDeviceDashboardActivity
Starting: Intent { cmp=com.android.settings/.Settings$ConnectedDeviceDashboardActivity }
console:/ # 

通过对比发现大概规律是:

1、activity中name=".Settings$XXXActivity"  可以通过 "start  -n 包名/.类名"启动界面

2、activity中name="Settings$XXXActivity"  不一定能通过 "start  -n 包名/.类名"启动界面 

3、如果activity有定义targetActivity 重定向的,可以查看具体重定义的Activity,查看是否可以可以通过包名和类名跳转;

对不对还要验证一下:

下面是AndroidManifest的其他类似定义:

//热点设置界面:
        <activity
            android:name="Settings$TetherSettingsActivity"
            android:label="@string/tether_settings_title_all"
            android:exported="true"
            android:icon="@drawable/ic_homepage_network">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.settings.TETHER_SETTINGS" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.VOICE_LAUNCH" />
            </intent-filter>
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                android:value="com.android.settings.network.tether.TetherSettings" />
            <meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
                       android:value="@string/menu_key_network"/>
        </activity>

//时间日期设置界面:
		<activity
            android:name="Settings$DateTimeSettingsActivity"
            android:label="@string/date_and_time"
            android:exported="true"
            android:icon="@drawable/ic_settings_date_time">
            <intent-filter android:priority="1">
                <action android:name="android.settings.DATE_SETTINGS" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.QUICK_CLOCK" />
                <category android:name="android.intent.category.VOICE_LAUNCH" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

上面两个Activity 都是可以通过start -n 拉起界面的;所以上面的最开始结论并不对。

正确的结论就是Activity能否拉起关键是否定义: “android.intent.action.MAIN”

<intent-filter>
    <action android:name="android.intent.action.MAIN" /> //Activity能否显示的关键
    <action android:name="android.intent.XXX" />
</intent-filter>

这个其实是Activity的一个基本知识:

<activity> 标签用于定义一个 Activity 组件。
<intent-filter> 标签则用来描述该 Activity 能够响应的意图。
<action android:name="android.intent.action.MAIN" /> 表明这个 Activity 是应用的主入口点。
<category android:name="android.intent.category.LAUNCHER" /> 表示这个 Activity 会在设备的应用启动器中显示图标,用户可以通过点击图标来启动应用。

开发者设置界面的Activity就是不想随意暴露所以才去除了MAIN定义。

3、 Toast提示: dev_settings_disabled_warning的代码

Settings 有一个Activity 的代码中Toast后就关闭应用了:

public class DevelopmentSettingsDisabledActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Toast.makeText(this, R.string.dev_settings_disabled_warning, Toast.LENGTH_SHORT).show();
        finish();
    }
}

从代码中未看到应用启动这个 DevelopmentSettingsDisabledActivity 界面。

  <activity
        android:name=".development.DevelopmentSettingsDisabledActivity"
        android:icon="@drawable/ic_settings_development"
        android:label="@string/development_settings_title"
        android:excludeFromRecents="true"
        android:exported="true"
        android:theme="@style/Transparent">
        <intent-filter android:priority="-1">
            <action android:name="android.settings.APPLICATION_DEVELOPMENT_SETTINGS" />
            <action android:name="com.android.settings.APPLICATION_DEVELOPMENT_SETTINGS" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

从AndroidManifest中只看到了定义的地方,也是监听了拉起开发者设置界面的action;

难道是两个Activity都监听了action,打开后进行 abortBroadcast();拦截广播?

但是全局搜索了并没有代码监听广播和蓝牙广播。

所以这个就比较奇怪,后续有人研究后,知道了的可以跟我说说哈。

4、Android原生设置Settings 具体Fragment和Activity界面跳转实现

上面跳转到开发者设置界面有个跳转到Fragment的命令:

am start -n com.android.settings/com.android.settings.SubSettings --es ":settings:show_fragment"  "com.android.settings.development.DevelopmentSettingsDashboardFragment"

如果想知道Settings中还有哪些Activity或者Fragment可以直接使用命令跳转可以看看:

https://blog.csdn.net/wenzhi20102321/article/details/140895222

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峥嵘life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值