我希望能够绕过这一步,让我的应用程序以编程方式获得 root 权限,而无需单击 SuperSu 对话框上的“授予”按钮。
你不能。用户必须授予您的应用 root 访问权限。除非您构建自己的 SU 管理应用程序,否则您无法绕过此初始权限请求。
我正在为设备提供应用程序,然后用户使用该设备(我拥有)。只是为了提供更多上下文,当我发布设备时,它已经拥有应用程序并且已经被 SuperSu 授予 root 访问权限。因此,我要避免的是应用程序可能会失去许可,然后在现场再次请求许可的情况。用户不精通技术,他们不知道 SuperSu 对话框是什么或如何处理它。
如果您拥有该设备,则可以在 SuperSu 设置中将“默认访问权限”更改为“授予”。您也可以针对每个应用进行更改。
您在 cmets 中提到您的应用已经拥有超级用户权限。您拥有 root 访问权限,因此您可以更改 SuperSu 的共享首选项,让您的应用始终被授予访问权限。同样,您暗示您拥有该设备,因此您不需要以编程方式修改 SuperSu 首选项。
如果您确实需要修改 SuperSu 的首选项,则以下代码应更改应用的访问设置以始终允许和禁用通知(使用 android-shell):
@WorkerThread
public static boolean tryChangingSuperSuDefaultAccess(Context context) throws Exception {
String packageName = context.getPackageName();
PackageManager pm = context.getPackageManager();
// Get the preferences for SuperSu
Context packageContext = context.createPackageContext("eu.chainfire.supersu", 0);
SharedPreferences superSuPrefs = PreferenceManager.getDefaultSharedPreferences(packageContext);
File superSuPrefsFile = getSharedPreferencesFile(superSuPrefs);
// Copy SuperSu preferences to our app's shared_prefs directory
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
File directory = getSharedPreferencesFile(preferences).getParentFile();
File destination = new File(directory, "eu.chainfire.supersu.xml");
int uid = pm.getApplicationInfo(context.getPackageName(), 0).uid;
destination.getParentFile().mkdirs();
Shell.SU.run("cp \"" + superSuPrefsFile + "\" \"" + destination + "\"");
Shell.SU.run("chmod 0660 \"" + destination + "\"");
Shell.SU.run("chown " + uid + " " + uid + " \"" + destination + "\"");
// Now we can edit the shared preferences
superSuPrefs = context.getSharedPreferences("eu.chainfire.supersu", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = superSuPrefs.edit();
editor.putString(String.format("config_%s_notify", packageName), "no"); // disable SuperSu notifications
editor.putString(String.format("config_%s_access", packageName), "grant"); // Set access to grant for this app
// noinspection all
editor.commit();
// Copy the edited shared preferences back
return Shell.SU.run("cp \"" + destination + "\" \"" + superSuPrefsFile + "\"").isSuccessful();
}
private static File getSharedPreferencesFile(SharedPreferences preferences)
throws NoSuchFieldException, IllegalAccessException {
Field field = preferences.getClass().getDeclaredField("mFile");
if (!field.isAccessible()) field.setAccessible(true);
return (File) field.get(preferences);
}
我不建议使用上面的代码。您应该保持透明并教育您的用户。如果您声称拥有该设备,则可以使用该应用自行更改这些设置。