7

我正在尝试编写必须在另一个应用程序的共享首选项(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)

有没有办法我可以做到这一点?

4

5 回答 5

10

要实际回答您的问题,如果您有根,则可以通过反射来完成。我已经在 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();
于 2013-08-08T10:42:52.217 回答
2

看看这个答案:

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

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

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

于 2013-01-25T12:56:12.670 回答
1

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

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

在我下面的解决方案中,我挂钩了类的onCreate方法Application,然后我得到了Context我想要编辑它的应用程序的保留SharedPreferences,然后我使用. 这里是:ContextSharedPreferences

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();
                }
            });
        }
    }
}

于 2019-02-26T11:19:43.607 回答
-1

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

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

于 2013-01-25T13:34:03.993 回答
-2

您不应该更改另一个应用程序的首选项,无论是否植根。

于 2013-01-25T12:46:32.037 回答