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