startActivity(new Intent(android.provider.Settings.ACTION_DEVICE_INFO_SETTINGS));
在Samsung设备中打开此页面:
但是,我希望它像其他Android设备一样打开此页面,我该怎么办?
最佳答案
要点是似乎不可能。让我们看看是什么原因。
可以通过如下意图调用来打开DeviceInfoSettingsActivity
:
Intent intent = new Intent(android.provider.Settings.ACTION_DEVICE_INFO_SETTINGS);
startActivity(intent);
或者Intent intent = new Intent();
intent.setClassName(
"com.android.settings",
"com.android.settings.Settings$DeviceInfoSettingsActivity"
);
startActivity(intent)
如您所见:Settings
及其所有内部类都是SettingsActivity
的子级。通过查看SettingsActivity
的源代码,我们发现可以显示一个子设置,将 fragment 名称作为附加意图将键":settings:show_fragment"
传递给SettingsActivity
:SettingsActivity#onCreate()
然后 SettingsActivity#launchSettingFragment()
如果我们深入研究显示目标屏幕的日志,则会发现目标 fragment 名称为
com.samsung.android.settings.deviceinfo.SoftwareInfoSettings
。但是问题是,在
SettingsActivity#isValidFragment()
上检查了 fragment 名称,这允许特定的 fragment 导航到它们,它们就是 SettingsGateway#ENTRY_FRAGMENTS
:protected boolean isValidFragment(String fragmentName) {
// Almost all fragments are wrapped in this,
// except for a few that have their own activities.
for (int i = 0; i < SettingsGateway.ENTRY_FRAGMENTS.length; i++) {
if (SettingsGateway.ENTRY_FRAGMENTS[i].equals(fragmentName)) return true;
}
return false;
}
在设置中显示其他 fragment 的替代方法是打开
SubSettings
Activity ,该 Activity 将覆盖 isValidFragment
以接受每个 fragment 。@Override
protected boolean isValidFragment(String fragmentName) {
Log.d("SubSettings", "Launching fragment " + fragmentName);
return true;
}
这就是显示SoftwareInfoSettings
时发生的情况:D/Settings: packageName : com.android.settings className : com.android.settings.SubSettings
D/SubSettings: Launching fragment com.samsung.android.settings.deviceinfo.SoftwareInfoSettings
不幸的是,除了启动程序的uid外,无法从SubSettings
启动uid
,因为这不是从外部可见的导出 Activity :AndroidManifest.xml:
<activity android:name=".SubSettings"
android:parentActivityName="Settings"
android:theme="@style/Theme.SubSettings"/>
如果您尝试运行:Intent intent = new Intent();
intent.setClassName(
"com.android.settings",
"com.android.settings.SubSettings"
);
intent.putExtra(
":settings:show_fragment",
"com.samsung.android.settings.deviceinfo.SoftwareInfoSettings"
);
startActivity(intent);
将看到此错误日志:E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.aminography.settingsapp, PID: 14566
java.lang.SecurityException: Permission Denial:
starting Intent { flg=0x10000000 cmp=com.android.settings/.SubSettings (has extras) }
from ProcessRecord{fac1d09 14566:com.aminography.settingsapp/u0a104} (pid=14566, uid=10104)
not exported from uid 1000
不幸的是,由于isValidFragment()
和SettingsGateway#ENTRY_FRAGMENTS
是平台的一部分,而不是应用程序的运行时,因此即使进行反射也无法更改它们。