android:sharedUserId="android.uid.system"从SD卡获取文件

android:sharedUserId="android.uid.system" Obtaining Files from SDCard

我在 Android (SDK 19/KitKat 4.4.2) 中有一个场景,我的应用程序将被签名为系统级应用程序 (App 1)在 Manifest.xml 中使用 android:sharedUserId="android.uid.system"。这意味着此应用程序无法写入或读取 SD 卡,无论是外部还是内置设备。

如果我需要从 SDCard 获取一个大文件并将其读入我的应用程序,执行此操作的最佳方法是什么?

我的目标只是从SDCard获取图像文件。但是,如果是未压缩的位图,即使是图像也可能相对较大。

我尝试了以下方法:

  1. 正在创建一个未作为系统用户签名的新应用程序 (App2)。从App1启动一个存在于这个App2的服务,然后从这里读取SD卡中的文件,然后获取到的byte[]文件,并通过 AIDL 将其分块发送到 App1。这在从 SDCard 读取文件并将其发送过来方面有效,但是 AIDL 的每个事务都有 1mb 的上限,而且速度也非常慢,以至于我可能应该限制允许提供给应用程序的图像大小使此功能可用。在我看来不是最理想的。

  2. 我已经尝试在 App 2 (UID: 10007) 中使用 FileProvider,但是在这种情况下我不需要打开任何图形界面 select我想要的文件和目标应用程序。我需要立即将它发送到 App 1 (UID: 10047) 或立即从 App1 获取它。我不确定是否可以在没有这些 gui 步骤的情况下使用 FileProvider。我尝试从 App2 创建 Uri,然后通过 AIDL 将 Uri 发送到 App1,然后通过 context.grantUriPermissions(packageName,uri ,READ/WRITE), 但总是以安全错误结束,其中 App1 没有权限读取 App2 提供的 uri。

java.lang.SecurityException:未找到 UID 10047 和 Uri 内容的权限授予://com.test.sdcard/folder/img.png

其中 UID 10047 是 App 1,UID 10007 是 App 2

这个问题还有其他解决方案吗?

系统应用程序无法从外部存储读取?这对我来说是个新闻,但无论如何。

您始终可以只创建一个管道,然后通过您选择的 IPC 机制(例如 ContentProvider.call())将读取端传回。服务端启动一个线程将文件写入写端,并将读端传回给客户端。在服务端是这样的:

  ParcelFileDescriptor[] fds;
  try {
    fds = ParcelFileDescriptor.createPipe();
  } catch (IOException e) {
    e.printStackTrace();
    return false;
  }

  final ParcelFileDescriptor readFd = fds[0];
  final ParcelFileDescriptor writeFd = fds[1];

  // TODO: start a thread to write file to writeFd

  Bundle result = new Bundle();
  extras.putParcelable(EXTRA_READ_FD, readFd);

  return result; // Return from call() to client

显然还有很多样板代码作为 reader.

的练习