Android:修改另一个应用程序的SharedPreferences

7

我正在尝试编写一个应用程序,该程序必须读取、修改和保存另一个应用程序(data/data/package_name/shared_prefs/file.xml)中的一些设置。

这个应用程序不是我的,我有一个用于测试的已经root的设备。

我应该在清单中添加哪些Android权限以及如何访问并修改此文件?我知道SharedPreferences对每个应用程序/APK都是唯一的,但我需要在root模式下修改它。

我有可以修改sdcard上xml文件的工作代码,但当我将路径更改为"data/data/package_name/shared_prefs/file.xml"时,它会给我一个异常和消息。

android open failed eacces (permission denied)

有没有什么方法可以实现这个目标?

你需要使用系统签名来签署你的应用程序,才能获得该权限,这并不容易获得。 - Nimish Choudhary
5个回答

10

实际回答您的问题,如果您有root权限,则可以使用反射来完成此操作。我已在Android 4.1上完成了此操作,在其他平台上可能会有所不同。好的是共享偏好设置只能被系统服务访问,因此您可以通过反射访问“隐藏”的方法。将以下内容放入try-catch中:

Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", "chmod 777 /data/data/package_name/shared_prefs/package_name_preferences.xml" });
proc.waitFor();
proc = Runtime.getRuntime().exec(new String[] { "su", "-c", "chmod 777 /data/data/package_name/shared_prefs" });
proc.waitFor();
proc = Runtime.getRuntime().exec(new String[] { "su", "-c", "chmod 777 /data/data/package_name" });
proc.waitFor();

File preffile = new File("/data/data/package_name/shared_prefs/package_name_preferences.xml");

Class prefimplclass = Class.forName("android.app.SharedPreferencesImpl");

Constructor prefimplconstructor = prefimplclass.getDeclaredConstructor(File.class,int.class);
prefimplconstructor.setAccessible(true);

Object prefimpl = prefimplconstructor.newInstance(preffile,Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);


Editor editor = (Editor) prefimplclass.getMethod("edit").invoke(prefimpl);
//put your settings here
editor.commit();

目录的权限更改可能不是必需的,只需要在实际的首选项文件上更改。当然,这会带来很多安全问题,但我假设您已经意识到了 root 的危险。 - azyoot
非常感谢,但是为什么我们要执行三次chmod 777? - Muhammad Babar

2

你能解释一下吗?我只需要运行SU并授予权限给我的应用程序,还是我需要在SU shell中执行特殊命令来更改文件属性? - Wolf6969
@Wolf6969,说实话,我只是出于好奇阅读了这些东西。但是,如果你阅读我链接的答案,似乎一旦你执行su,应用程序就会以超级用户权限运行。因此,您只需将第一行添加到代码中,之后您就不会遇到权限问题。我明天会尝试一下,但为什么不让你自己尝试呢? - Shade
那不是这样的。授予您的应用程序超级用户权限可以使您能够以root身份运行命令。应用程序本身仍在沙箱中运行,您将无法使用除'Runtime.exec() 命令或其他系统命令以外的任何内容访问那些shared_prefs。我建议使用su命令将文件复制到您具有读/写访问权限的位置(可能是您的应用程序数据文件夹),对其进行修改,然后使用另一个su`命令将其复制回来并覆盖现有文件。 - cnexus

1
我曾经遇到同样的问题,尝试了各种方法,包括在StackOverflow和其他网站上找到的建议,但都没有起作用。即使我的设备已经root,我仍然遇到了“无权限”的错误。
最后,我想出了一个优雅的解决方案,使用Xposed
在我的解决方案中,我钩取了Application类的onCreate方法,然后获取了我想要编辑其SharedPreferences的应用程序的Context,并使用该Context编辑SharedPreferences。以下是代码:

public class MainXposed implements IXposedHookLoadPackage{
    private static final String TAG = "MainXposed";

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        Log.d( TAG, "handleLoadPackage: loadPackageParam.packageName --> " + loadPackageParam.packageName );
        if ( loadPackageParam.packageName.contains( "com.someapp" ) ) {
    
            findAndHookMethod("android.app.Application", loadPackageParam.classLoader, "onCreate", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                
                }
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    Log.d( TAG, "afterHookedMethod()" );

                    String pkg = "com.someapp";
                    Application application = ( Application ) param.thisObject;
                    Context someappContext = application.getApplicationContext();
    
                    someappContext.createPackageContext( pkg ,Context.CONTEXT_IGNORE_SECURITY );
                    SharedPreferences someapp_prefs = someappContext.getSharedPreferences(pkg + "_preferences", Context.MODE_PRIVATE );
                    SharedPreferences.Editor editor = someapp_prefs.edit();
                    editor.putString( "some_prefs_key", "someNewValue" );
                    editor.apply();
                }
            });
        }
    }
}


-2

您不应该更改另一个应用程序的首选项,无论它是否已获得Root权限。


我可以在任何具有根模式的浏览器中完成此操作,为什么我不能从我的应用程序中完成此操作? - Wolf6969

-2

除非你是另一个应用程序的所有者,否则你不应该这样做。没有 root 的唯一方法是让它成为全局可读的,这已经过时并且几乎不再使用。

我怀疑除非你说明需要访问权限的原因,否则没有人会给你想要的答案。


这并不是什么秘密。此外,许多人使用root进行修改等目的。 - Shade
这并不改变你想要通过编程实现而不是人工手动操作的事实。 - Mgamerz
我的意思是有些应用程序需要root权限才能运行,但仍然提供好处(而不是伤害你)。当您在设备上使用自定义ROM时,您可能会遇到许多此类应用程序 - 例如用于修改导航栏(ICS +)的应用程序。 - Shade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接