Android ADB如何在不root的情况下访问应用程序数据库

37

有人能告诉我,在没有手机root权限的情况下,是否可以使用ADB来从应用程序中拉取和推送数据库吗?

例如,我知道我的已经root的Magic和Dream手机上的数据库位置是:

/data/data/com.xxxx.xxxx/databases/xxxx

我知道你可以在没有root权限的情况下使用ADB,但是如果尝试使用shell时,需要root权限才能查看该位置。但我被告知,如果你知道要获取的文件,你可以使用push和pull命令来实现?

基本上,我想从非root手机上的“我的应用程序”中提取数据库并进行修改,然后再将其推回去。

唯一的问题是,我手头拥有的两部手机都已经root,我无法使用非root手机进行尝试。


https://dev59.com/kWMl5IYBdhLWcg3wXF5f#18472135 - Alex P.
5个回答

80

虽然 Nilhcem 的回答对我无效,但它让我朝着正确的方向前进(因此我投了赞成票),现在我有一个可行的解决方案。

旧的回答可能在较新版本的 Android 上无法使用:

#Transfer file from app databases directory to PC
adb shell
$ run-as package.name
$ cd ./databases/
$ ls -l #Find the current permissions - r=4, w=2, x=1
$ chmod 666 ./dbname.db
$ exit
$ exit
adb pull /data/data/package.name/databases/dbname.db ~/Desktop/

#Transfer file from PC to app databases directory (requires the above permission change)
adb push ~/Desktop/dbname.db /data/data/package.name/databases/dbname.db
adb shell
$ run-as package.name
$ chmod 660 ./databases/dbname.db #Restore original permissions
$ exit
$ exit

使用外部存储的备选方法(已确认与6.0.1兼容):

#Transfer file from app databases directory to external storage
adb shell
$ run-as package.name
$ cp ./databases/dbname.db /sdcard/
$ exit
$ exit

#Transfer file from external storage to app databases directory
adb shell
$ run-as package.name
$ cp /sdcard/dbname.db ./databases/
$ exit
$ exit

1
这是一个正确的答案,适用于那些想要进行此操作的应用程序开发人员,并且可以安装调试版本(调试版本是run-as的先决条件)。其他选项包括让应用程序本身更改权限或将文件从/复制到外部存储。 - Chris Stratton
1
@um.anusorn 在4.3版本中存在一个问题,会破坏run-as功能,应该在4.4版本中修复。请参见:https://code.google.com/p/android/issues/detail?id=58373 如果您有root权限,可以通过启用/system/bin/run-as的Set UID权限来修复它,但这有点违背了初衷。 - Pilot_51
1
@um.anusorn 这可能意味着您的应用程序不是调试版本(在2.3上遇到了相同的问题)。 - halxinate
4
尽管文件明显存在并且已经应用了chmod 666,但是adb pull显示远程对象不存在。似乎你仍需要一些额外的权限才能执行此操作? - Sebastian Wramba
1
这个解决方法在 Android 5.1+ 不再适用。拉取文件会显示“远程对象文件名不存在”。答案应该反映这一点。 - Bogdan Zurac
显示剩余6条评论

13

一个快速解决方法是使用 run-as 命令将数据库复制到您可以访问的文件夹中,例如 /sdcard,然后进行正常的 adb pull

adb shell
$ run-as package.name cp /data/data/package.name/dbname.db /sdcard/
$ exit
adb pull /sdcard/dbname.db

关于 run-as 命令的更多信息,请参见此处

请注意,run-as命令自API级别8(Android 2.2)起可用,并且仅在应用程序处于可调试状态时才能使用。


在我的版本上(可能与4.4有关,或者是去年的某个更新?),当使用“run-as”时,我无法将文件复制到/sdcard。我需要使用@Pilot_51的“chmod”解决方案。 - Richard Le Mesurier
这是真的-在使用adb shell时,SD卡不再可写 - slott

1

在基于Android 5.2的OxygenOS上,我结合了Pilot_51提供的两种解决方案。

首先,我使用run-as获取访问/data/data/package.name/databases的权限,但是从这里我无法直接复制到/sdcard/,因此我更改了文件的权限。之后,我退出run-as模式并使用cp将文件复制到/sdcard/存储中。最后,我能够使用adb pull

$ adb -s <DEVICE_ID> shell
$ run-as package.name
$ chmod 666 databases/dbname.db
$ exit
$ cp /data/data/package.name/databases/dbname.db /sdcard/dbname.db
$ exit
$ adb pull /sdcard/dbname.db ./dbname.db

0

如果你想将数据库文件推送到应用程序中

首先,由于权限问题,请将“file.db”放置在“/storage/emulated/0/”下。然后,您应该假装成应用程序来访问数据文件夹。

  adb shell
  $ run-as com.package.name
  :/data/data/com.package.name $ cp /storage/emulated/0/file.db /data/data/com.package.name/databases/

它将位于主文件夹中的file.db文件复制到databases文件夹中。


0
我们在应用程序内部将文件权限设置为可读取,适用于所有用户。
if (BuildConfig.DEBUG)
{
    new File(mDB.getPath()).setReadable(true, false);
}

然后就可以用adb正常地将.db文件拉出来了。

adb -d pull //data/data/xxxxx/databases/xxxxx.db .

注意:我发现每次打开数据库文件(例如,在onCreate中和SQLiteOpenHelper包装器的构造函数中,当数据库不为null时)都需要执行此操作,或者可能在onOpen中执行。 如果仅在onCreate中执行,则下次运行应用程序并且.db已经存在时,由于某种原因权限已被更改回来。这可能与Android如何管理其数据有关。


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