简体   繁体   English

android:sharedUserId =“ android.uid.system”从SDCard获取文件

[英]android:sharedUserId=“android.uid.system” Obtaining Files from SDCard

I have a scenario in Android (SDK 19/KitKat 4.4.2) where my application is to be signed as a system level application ( App 1 ) using android:sharedUserId="android.uid.system" in the Manifest.xml. 我在Android(SDK 19 / KitKat 4.4.2)中有一个场景,其中我的应用程序将使用Manifest.xml中的android:sharedUserId =“ android.uid.system”签名为系统级应用程序( App 1 )。 This means that this application is unable to write or read from SD cards, be they external or built into the device. 这意味着该应用程序无法从SD卡写入或读取数据,无论它们是外部的还是内置在设备中的。

If I needed to obtain a large file from the SDCard and read it into my application, what is the best approach to do this? 如果需要从SDCard获取大文件并将其读入应用程序,什么是最好的方法?

My goal is simply to obtain image files from the SDCard. 我的目标仅仅是从SDCard获取图像文件。 However, even images can be relatively big if they're uncompressed bitmaps. 但是,即使图像是未压缩的位图,它们也可能相对较大。

I've tried the following approaches: 我尝试了以下方法:

  1. Creating a new application that is not signed as the system user ( App2 ). 创建未签名为系统用户的新应用程序( App2 )。 Starting a service that exists in this App2 from App1 , then reading in the file from the SD card from here, then obtaining the byte[] of the file, and sending it over via AIDL to App1 in chunks. App1启动此App2中存在的服务,然后从此处从SD卡读取文件,然后获取文件的byte [],然后通过AIDL将其分块发送到App1 This works in terms of reading the file from the SDCard and sending it over, however AIDL has a cap of 1mb for each transaction and is also very slow to a point where I should probably limit the size of images allowed to be given to the application to make this feature usable. 这可以从SDCard读取文件并将其发送出去,但是AIDL每笔交易的上限为1mb,而且还很慢,我应该限制允许提供给应用程序的图像大小使此功能可用。 Not the most ideal in my opinion. 我认为这不是最理想的。

  2. I've tried using FileProvider in App 2 (UID: 10007) , however in this scenario I need to not open any graphical interface to select the file I want and a target application. 我尝试在App 2(UID:10007)中使用FileProvider,但是在这种情况下,我无需打开任何图形界面来选择所需的文件和目标应用程序。 I need to just send it over immediately to App 1 (UID: 10047) or obtain it immediately from App1 . 我需要立即将其发送到App 1(UID:10047)或立即从App1获得它。 I'm not sure if it's possible to use FileProvider without those gui steps. 我不确定如果没有这些gui步骤,是否可以使用FileProvider。 I tried just creating the Uri from App2 then sending the Uri to App1 over AIDL, then giving permissions via context.grantUriPermissions(packageName,uri,READ/WRITE), but always end up with a security error where App1 does not have permission to read the uri App2 is providing. 我尝试仅从App2创建Uri,然后通过AIDL将Uri发送到App1 ,然后通过context.grantUriPermissions(packageName,uri,READ / WRITE)授予权限,但是始终以安全错误结尾,其中App1没有读取权限uri App2正在提供。

java.lang.SecurityException: No permission grant found for UID 10047 and Uri content://com.test.sdcard/folder/img.png java.lang.SecurityException:未找到针对UID 10047和Uri的权限授予content://com.test.sdcard/folder/img.png

Where UID 10047 is App 1 and UID 10007 is App 2 . 其中UID 10047是App 1 ,UID 10007是App 2

Any alternative solutions to this problem? 有其他解决方案吗?

A system app can't read from external storage? 系统应用无法从外部存储读取? That's news to me, but anyway. 这对我来说是个新闻,但无论如何。

You can always just create a pipe and pass the read end back over the IPC mechanism of your choice ( ContentProvider.call() for example). 您始终可以只创建一个管道,然后将读取端传递回您选择的IPC机制ContentProvider.call()例如ContentProvider.call() )。 The service-side starts a thread and writes the file to the write end, and passes the read end back to the client. 服务端启动线程并将文件写入写端,然后将读端传递回客户端。 Something like this on the service side: 在服务端这样的事情:

  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

Obviously there is a lot of boilerplate code left as an exercise for the reader. 显然,还有许多样板代码可供读者练习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM