0

I am trying to make user pick an image from gallery, display it in imageView, and at the same time, create a byte array of the same file.

After debugging:

'new File(filepath)' executed no problem, with a valid filesystem path.

but it always skips 'ByteArrayOutputStream baos = new ByteArrayOutputStream();' to the IOException with a java.ioFileNotFoundException

any idea what im doing wrong?

or is there a more efficient way i can just convert a byte of a file to a HEX character, and send each HEX char until the last byte of the file?

try {
                    File myFile = new File(imageUri.getPath());
                    String filepath = myFile.getAbsolutePath();
                    Log.d("onActivityResult", "filepath: " + filepath);
                    FileOutputStream fos = new FileOutputStream ( new File(filepath) );
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();

                    // Put data in your baos

                    baos.writeTo(fos);
                } catch(IOException ioe) {
                    // Handle exception here
                    ioe.printStackTrace();
                    Toast.makeText(this, "Byte buffer error.", Toast.LENGTH_LONG).show();
                }
7
  • 1
    GET_CONTENT or equivalent methods of picking an image does not return a File with a path on recent versions of Android. Commented Sep 27, 2017 at 21:23
  • @ianhanniballake which is why i used the uri to the image/file to get the absolute file path. the debug shows the filepath to be correct(the file location of image i picked) Commented Sep 27, 2017 at 21:53
  • Even then, you won't have read permissions to the file. Only to the Uri. Commented Sep 27, 2017 at 22:08
  • 1
    A FileNotFoundException very clearly points to the fact that no, you do not have a valid File. Commented Sep 28, 2017 at 4:32
  • 1
    That does not mean you have access to the file. File permissions are completely and totally independent from the content URI permissions you get when you use GET_CONTENT. Commented Sep 28, 2017 at 20:15

1 Answer 1

2

any idea what im doing wrong?

You think that a Uri always points to a file.

If the scheme of the Uri is file, then getPath() will be a filesystem path. Depending on how you got the Uri, that filesystem path may be usable.

Most of the time, the Uri will have a different scheme, typically content. For such a Uri, getPath() is meaningless, just as getPath() is meaningless for a Uri like https://stackoverflow.com/questions/46457384/error-when-converting-file-to-byte-array-java-iofilenotfoundexception.

For a Uri with a scheme of content (or file, or android.resource), use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri.

Even if you fix that, you will crash most of the time with an OutOfMemoryError, as you will not have a single contiguous block of free heap space to load the entire content that the user chose.

Sign up to request clarification or add additional context in comments.

5 Comments

for my app's usage, i believe my Uri always points to a file, since it only opens the gallery for users to select images.. I've debugged my code and 'new File(filepath)' executed no problem, with a valid filesystem path. The image i need in a byte array are typically never bigger than 0.5MB, so heap memory should not be an issue, although your point is valid. is there a way i can just convert a byte of a file to a HEX character, and send each HEX char until the last byte of the file?
@tzj: "i believe my Uri always points to a file" -- look at the scheme, rather than making assumptions. "it only opens the gallery for users to select images" -- most ACTION_GET_CONTENT activities have returned Uri values with content schemes for a few years now. "I've debugged my code and 'new File(filepath)' executed no problem" -- new File() simply creates an instance of a File object and performs no validation on the supplied string.
@tzj: "The image i need in a byte array are typically never bigger than 0.5MB" -- the user can choose anything, and most images in the gallery will be much bigger than 0.5MB. "is there a way i can just convert a byte of a file to a HEX character, and send each HEX char until the last byte of the file?" -- I do not know what you mean by "send", as the code in your question is not sending anything anywhere.
"the user can choose anything" technically, you are right, but i will need to do a formatter that limits the image to be 144pixels * x pixels. Hence which usually is at best afew KB, unless the image is very long. " I do not know what you mean.. " on android, it reads a file, and convert every byte of the file chosen to a HEX representation, which will be sent via BLE to my mcu(which then reconstruct the file n stores in its SD card). I have already done the sending function correctly. i just want to get the file conversion correct first before integrating both functions.
@tzj: Um, well, converting UTF8 into hex already works on a byte-by-byte basis. So, read in a small block (e.g., 1024 bytes), convert that, send it along via BLE, read in the next block, convert that, send it along via BLE, etc. Copying files, compressing files, encrypting files, etc. have worked in a streaming fashion (converting small blocks at a time) for decades.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.