android:sharedUserId=“android.uid.system” Obtaining Files from SDCard
up vote
0
down vote
favorite
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. This means that this application is unable to write or read from SD cards, be they external or built into the device.
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?
My goal is simply to obtain image files from the SDCard. However, even images can be relatively big if they're uncompressed bitmaps.
I've tried the following approaches:
Creating a new application that is not signed as the system user (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. 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. Not the most ideal in my opinion.
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. I need to just send it over immediately to App 1 (UID: 10047) or obtain it immediately from App1. I'm not sure if it's possible to use FileProvider without those gui steps. 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.
java.lang.SecurityException: No permission grant found for UID 10047 and Uri content://com.test.sdcard/folder/img.png
Where UID 10047 is App 1 and UID 10007 is App 2.
Any alternative solutions to this problem?
android system android-4.4-kitkat aidl
add a comment |
up vote
0
down vote
favorite
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. This means that this application is unable to write or read from SD cards, be they external or built into the device.
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?
My goal is simply to obtain image files from the SDCard. However, even images can be relatively big if they're uncompressed bitmaps.
I've tried the following approaches:
Creating a new application that is not signed as the system user (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. 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. Not the most ideal in my opinion.
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. I need to just send it over immediately to App 1 (UID: 10047) or obtain it immediately from App1. I'm not sure if it's possible to use FileProvider without those gui steps. 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.
java.lang.SecurityException: No permission grant found for UID 10047 and Uri content://com.test.sdcard/folder/img.png
Where UID 10047 is App 1 and UID 10007 is App 2.
Any alternative solutions to this problem?
android system android-4.4-kitkat aidl
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
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. This means that this application is unable to write or read from SD cards, be they external or built into the device.
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?
My goal is simply to obtain image files from the SDCard. However, even images can be relatively big if they're uncompressed bitmaps.
I've tried the following approaches:
Creating a new application that is not signed as the system user (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. 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. Not the most ideal in my opinion.
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. I need to just send it over immediately to App 1 (UID: 10047) or obtain it immediately from App1. I'm not sure if it's possible to use FileProvider without those gui steps. 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.
java.lang.SecurityException: No permission grant found for UID 10047 and Uri content://com.test.sdcard/folder/img.png
Where UID 10047 is App 1 and UID 10007 is App 2.
Any alternative solutions to this problem?
android system android-4.4-kitkat aidl
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. This means that this application is unable to write or read from SD cards, be they external or built into the device.
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?
My goal is simply to obtain image files from the SDCard. However, even images can be relatively big if they're uncompressed bitmaps.
I've tried the following approaches:
Creating a new application that is not signed as the system user (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. 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. Not the most ideal in my opinion.
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. I need to just send it over immediately to App 1 (UID: 10047) or obtain it immediately from App1. I'm not sure if it's possible to use FileProvider without those gui steps. 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.
java.lang.SecurityException: No permission grant found for UID 10047 and Uri content://com.test.sdcard/folder/img.png
Where UID 10047 is App 1 and UID 10007 is App 2.
Any alternative solutions to this problem?
android system android-4.4-kitkat aidl
android system android-4.4-kitkat aidl
edited Nov 8 at 19:14
Kling Klang
32.2k156287
32.2k156287
asked Nov 8 at 18:36
Jetompki
215
215
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
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). 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.
Struggling with this approach. Could you illustrate an example with how you write data into the writeEnd, then read the data back using the readEnd? I was following this stackoverflow.com/questions/18212152/… which seems similar to what you suggest, but I encountered the error mentioned with java.io.IOException: read failed: EBADF (Bad file number)
– Jetompki
Nov 8 at 23:18
Nevermind, managed to figure it out using the getFileDescriptor(byte data) snippet from here. stackoverflow.com/questions/51902834/…
– Jetompki
Nov 9 at 16:53
I have a concern regarding the start of the thread on the service side, and the reading of the Descriptor on the client side. In the snippet you provide, it seems that the client can retrieve the readEnd before there is actually any data to be read, given that you spawn a thread to write to the writeEnd. I tried implementing a delay (thread.sleep) in the thread to write on the service side, but it seems that my client is able to read the data fine regardless (albeit delayed) despite that I start my read on the client side as soon as that result in your snippet is returned. Why does this work?
– Jetompki
Nov 9 at 21:50
If nothing is written to the read end (yet), the IO will block. The pipe is still open. Think of it like making a network request and the server hasn't returned any data yet. The network request doesn't fail just because there's no data to read.
– Jeffrey Blattman
Nov 9 at 21:55
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
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). 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.
Struggling with this approach. Could you illustrate an example with how you write data into the writeEnd, then read the data back using the readEnd? I was following this stackoverflow.com/questions/18212152/… which seems similar to what you suggest, but I encountered the error mentioned with java.io.IOException: read failed: EBADF (Bad file number)
– Jetompki
Nov 8 at 23:18
Nevermind, managed to figure it out using the getFileDescriptor(byte data) snippet from here. stackoverflow.com/questions/51902834/…
– Jetompki
Nov 9 at 16:53
I have a concern regarding the start of the thread on the service side, and the reading of the Descriptor on the client side. In the snippet you provide, it seems that the client can retrieve the readEnd before there is actually any data to be read, given that you spawn a thread to write to the writeEnd. I tried implementing a delay (thread.sleep) in the thread to write on the service side, but it seems that my client is able to read the data fine regardless (albeit delayed) despite that I start my read on the client side as soon as that result in your snippet is returned. Why does this work?
– Jetompki
Nov 9 at 21:50
If nothing is written to the read end (yet), the IO will block. The pipe is still open. Think of it like making a network request and the server hasn't returned any data yet. The network request doesn't fail just because there's no data to read.
– Jeffrey Blattman
Nov 9 at 21:55
add a comment |
up vote
1
down vote
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). 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.
Struggling with this approach. Could you illustrate an example with how you write data into the writeEnd, then read the data back using the readEnd? I was following this stackoverflow.com/questions/18212152/… which seems similar to what you suggest, but I encountered the error mentioned with java.io.IOException: read failed: EBADF (Bad file number)
– Jetompki
Nov 8 at 23:18
Nevermind, managed to figure it out using the getFileDescriptor(byte data) snippet from here. stackoverflow.com/questions/51902834/…
– Jetompki
Nov 9 at 16:53
I have a concern regarding the start of the thread on the service side, and the reading of the Descriptor on the client side. In the snippet you provide, it seems that the client can retrieve the readEnd before there is actually any data to be read, given that you spawn a thread to write to the writeEnd. I tried implementing a delay (thread.sleep) in the thread to write on the service side, but it seems that my client is able to read the data fine regardless (albeit delayed) despite that I start my read on the client side as soon as that result in your snippet is returned. Why does this work?
– Jetompki
Nov 9 at 21:50
If nothing is written to the read end (yet), the IO will block. The pipe is still open. Think of it like making a network request and the server hasn't returned any data yet. The network request doesn't fail just because there's no data to read.
– Jeffrey Blattman
Nov 9 at 21:55
add a comment |
up vote
1
down vote
up vote
1
down vote
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). 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.
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). 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.
answered Nov 8 at 19:32
Jeffrey Blattman
16.4k564114
16.4k564114
Struggling with this approach. Could you illustrate an example with how you write data into the writeEnd, then read the data back using the readEnd? I was following this stackoverflow.com/questions/18212152/… which seems similar to what you suggest, but I encountered the error mentioned with java.io.IOException: read failed: EBADF (Bad file number)
– Jetompki
Nov 8 at 23:18
Nevermind, managed to figure it out using the getFileDescriptor(byte data) snippet from here. stackoverflow.com/questions/51902834/…
– Jetompki
Nov 9 at 16:53
I have a concern regarding the start of the thread on the service side, and the reading of the Descriptor on the client side. In the snippet you provide, it seems that the client can retrieve the readEnd before there is actually any data to be read, given that you spawn a thread to write to the writeEnd. I tried implementing a delay (thread.sleep) in the thread to write on the service side, but it seems that my client is able to read the data fine regardless (albeit delayed) despite that I start my read on the client side as soon as that result in your snippet is returned. Why does this work?
– Jetompki
Nov 9 at 21:50
If nothing is written to the read end (yet), the IO will block. The pipe is still open. Think of it like making a network request and the server hasn't returned any data yet. The network request doesn't fail just because there's no data to read.
– Jeffrey Blattman
Nov 9 at 21:55
add a comment |
Struggling with this approach. Could you illustrate an example with how you write data into the writeEnd, then read the data back using the readEnd? I was following this stackoverflow.com/questions/18212152/… which seems similar to what you suggest, but I encountered the error mentioned with java.io.IOException: read failed: EBADF (Bad file number)
– Jetompki
Nov 8 at 23:18
Nevermind, managed to figure it out using the getFileDescriptor(byte data) snippet from here. stackoverflow.com/questions/51902834/…
– Jetompki
Nov 9 at 16:53
I have a concern regarding the start of the thread on the service side, and the reading of the Descriptor on the client side. In the snippet you provide, it seems that the client can retrieve the readEnd before there is actually any data to be read, given that you spawn a thread to write to the writeEnd. I tried implementing a delay (thread.sleep) in the thread to write on the service side, but it seems that my client is able to read the data fine regardless (albeit delayed) despite that I start my read on the client side as soon as that result in your snippet is returned. Why does this work?
– Jetompki
Nov 9 at 21:50
If nothing is written to the read end (yet), the IO will block. The pipe is still open. Think of it like making a network request and the server hasn't returned any data yet. The network request doesn't fail just because there's no data to read.
– Jeffrey Blattman
Nov 9 at 21:55
Struggling with this approach. Could you illustrate an example with how you write data into the writeEnd, then read the data back using the readEnd? I was following this stackoverflow.com/questions/18212152/… which seems similar to what you suggest, but I encountered the error mentioned with java.io.IOException: read failed: EBADF (Bad file number)
– Jetompki
Nov 8 at 23:18
Struggling with this approach. Could you illustrate an example with how you write data into the writeEnd, then read the data back using the readEnd? I was following this stackoverflow.com/questions/18212152/… which seems similar to what you suggest, but I encountered the error mentioned with java.io.IOException: read failed: EBADF (Bad file number)
– Jetompki
Nov 8 at 23:18
Nevermind, managed to figure it out using the getFileDescriptor(byte data) snippet from here. stackoverflow.com/questions/51902834/…
– Jetompki
Nov 9 at 16:53
Nevermind, managed to figure it out using the getFileDescriptor(byte data) snippet from here. stackoverflow.com/questions/51902834/…
– Jetompki
Nov 9 at 16:53
I have a concern regarding the start of the thread on the service side, and the reading of the Descriptor on the client side. In the snippet you provide, it seems that the client can retrieve the readEnd before there is actually any data to be read, given that you spawn a thread to write to the writeEnd. I tried implementing a delay (thread.sleep) in the thread to write on the service side, but it seems that my client is able to read the data fine regardless (albeit delayed) despite that I start my read on the client side as soon as that result in your snippet is returned. Why does this work?
– Jetompki
Nov 9 at 21:50
I have a concern regarding the start of the thread on the service side, and the reading of the Descriptor on the client side. In the snippet you provide, it seems that the client can retrieve the readEnd before there is actually any data to be read, given that you spawn a thread to write to the writeEnd. I tried implementing a delay (thread.sleep) in the thread to write on the service side, but it seems that my client is able to read the data fine regardless (albeit delayed) despite that I start my read on the client side as soon as that result in your snippet is returned. Why does this work?
– Jetompki
Nov 9 at 21:50
If nothing is written to the read end (yet), the IO will block. The pipe is still open. Think of it like making a network request and the server hasn't returned any data yet. The network request doesn't fail just because there's no data to read.
– Jeffrey Blattman
Nov 9 at 21:55
If nothing is written to the read end (yet), the IO will block. The pipe is still open. Think of it like making a network request and the server hasn't returned any data yet. The network request doesn't fail just because there's no data to read.
– Jeffrey Blattman
Nov 9 at 21:55
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53214114%2fandroidshareduserid-android-uid-system-obtaining-files-from-sdcard%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown