【问题标题】:Android: Modify SharedPreferences of another appAndroid:修改另一个应用程序的 SharedPreferences
【发布时间】:2013-01-25 12:42:21
【问题描述】:

我正在尝试编写必须读取、修改和保存其他应用程序的共享首选项中的某些设置的应用程序 (data/data/package_name/shared_prefs/file.xml)。

这个应用程序不是我的,我已经root了设备进行测试。

我应该向清单添加哪些 android 权限以及如何访问该文件并对其进行修改?我知道SharedPreferences对于每个App/APK都是唯一的,但是我需要在root模式下修改它。

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

android open failed eacces (permission denied)

有什么方法可以实现吗?

【问题讨论】:

  • 您需要使用系统签名为您的应用程序签名以获得该权限,这并不容易。

标签: android sharedpreferences root


【解决方案1】:

要真正回答您的问题,如果您有 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 的危险。
  • 非常感谢,但为什么我们必须执行 chmod 777 3 次?
【解决方案2】:

看看这个答案:

https://stackoverflow.com/a/13139280/361230

当您使用 su 时,您将有权修改文件系统上的任何内容。

但是,我同意 Chris 的观点,即按照自己的意愿去做并不是一件好事。

【讨论】:

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

我遇到了同样的问题,我尝试了所有方法,我在 StackOverflow 和网络上的其他地方找到的每条建议都没有任何帮助。即使我的设备已植根,我总是以“无权限”错误结束。

最后,我想出了一个使用Xposed 的优雅解决方案。

在下面的解决方案中,我连接了Application 类的onCreate 方法,然后我将要编辑它的应用程序的Context 保留为SharedPreferences,然后我我正在使用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();
                }
            });
        }
    }
}

【讨论】:

    【解决方案4】:

    除非您是其他应用程序的所有者,否则您不应该这样做。没有 root 的唯一方法是让它成为世界可读的,它已被贬值并且几乎从未使用过。

    我怀疑有人会给你一个你想要的答案,除非你说明你为什么需要访问权限。

    【讨论】:

    • 这不像是秘密什么的。此外,许多人正在使用 root 进行改装等。
    • 这并没有改变您希望以编程方式执行此操作而不是手动执行此操作的事实。
    • 我的意思是有些应用程序需要 root 才能运行,但仍然可以提供好处(而不是伤害您)。在您的设备上使用自定义 ROM 时会遇到许多此类应用程序 - f.e.用于修改导航栏 (ICS+) 的应用程序。
    【解决方案5】:

    您不应更改其他应用的偏好设置,无论是否已root。

    【讨论】:

    • 我可以通过任何具有 root 模式的资源管理器执行此操作,为什么我不能在我的应用程序中执行此操作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多