以编程方式正确打开“设置”中的 'About device' 页面?

Programmatically open 'About device' page in Settings correctly?

startActivity(new Intent(android.provider.Settings.ACTION_DEVICE_INFO_SETTINGS)); 在三星设备中打开此页面:

但是,我希望它像其他 Android 设备一样打开此页面,我该怎么做?

正如 android 文档所说,您应该使用

Intent i = new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS);
startActivity(i);

https://developer.android.com/reference/android/provider/Settings#ACTION_DEVICE_INFO_SETTINGS

如果它不适用于 SAMSUNG 设备,恐怕它可能无法实现。至少没有官方答案。很多时候供应商修改库存 Android 因此三星设备的设置应用程序与库存 AOSP 不同,官方方法将不起作用。

正如 佩德罗·安东尼奥 所说:

If it doesn't work for SAMSUNG devices I'm afraid it will probably not be possible. At least with no official answer. Many times vendors modify stock Android so for SAMSUNG devices settings app is different than stock AOSP, and the official method will not work.

当我们调用:

Intent i = new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS);
startActivity(i);

我们指的是 activity com.android.settings.Settings$DeviceInfoSettingsActivity,在日志中我们可以看到 activity 已启动

2020-06-26 11:33:43.804 4838-5126/? I/ActivityManager: START u0 {act=null typ=null flg=0x8000 cmp=ComponentInfo{com.android.settings/com.android.settings.Settings$DeviceInfoSettingsActivity}} from uid 1000

在华为 P10 等设备上,软件信息数据是 DeviceInfoSettingsActivity 的一部分。经过一番挖掘后,我发现在三星 S7 设备上,软件信息是在 DeviceInfoSettingsActivity

中调用的片段
2020-06-26 11:44:25.780 7103-9703/? D/Settings: packageName : com.android.settings className : com.android.settings.SubSettings
2020-06-26 11:44:25.812 7103-7103/? D/SubSettings: Launching fragment com.samsung.android.settings.deviceinfo.SoftwareInfoSettings

我不确定是否可以访问 DeviceInfoSettingsActivity 代码(我不能),看看您是否可以发送一些额外的数据来打开特定的片段。所以在这一点上我不相信有可能从意图中启动那个特定的片段。

重点是好像不可能。让我们看看是什么原因。

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)

如您所见:

https://android.googlesource.com/platform/packages/apps/Settings/+/master/src/com/android/settings/Settings.java

Settings 及其所有内部 类 都是 SettingsActivity 的子代。通过查看 SettingsActivity 的源代码,我们发现可以显示子设置,将片段名称作为带有键 ":settings:show_fragment" 的 intent extra 传递给 SettingsActivity

SettingsActivity#onCreate() then SettingsActivity#launchSettingFragment()

如果我们深入查看显示目标屏幕的日志,我们会发现目标片段名称是 com.samsung.android.settings.deviceinfo.SoftwareInfoSettings

但问题是在 SettingsActivity#isValidFragment() which allows specific fragments to navigate to and they are 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;
}

在设置中显示其他片段的替代方法是打开 SubSettings activity which overrides the isValidFragment 接受每个片段。

@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 是平台的一部分,而不是您的应用程序的 运行time,因此即使通过反射也无法更改它们。