Question

I'm writing an application that needs to read two image files for various purposes.

One of the image files is received through an intent-filter, and I open it in this way (note: mIntent is the result of getIntent()):

mFileUri = (Uri) mIntent.getParcelableExtra(Intent.EXTRA_STREAM);
mInputStream = getContentResolver().openInputStream(mFileUri);

Then reading mInputStream works as expected.

The problem is reading the second image file: it's Uri (converted using toString()) is written in a shared preference, I get the value and use Uri.parse() to restore it, as "default value" argument in the getString() call I use the Uri of a local resource located in the assets subdirectory (android.resource scheme). The way I try to read it is the same, using getContentResolver().openInputStream(), but something goes wrong: calling read() on the returned InputStream always return -1. I've also tried getAssets().open(), but it doesn't work, either with an android.resource or a content scheme Uri. Note: with the intent-received file I use read(byte[]), while with the second one I use read().

So, here is my question: why does this happen and how can I solve this problem?

Was it helpful?

Solution

I was right: it is a bug in the AssetInputStream implementation due to the lack of distinction between EOF and I/O errors in the native method _FileAsset::read(void *, size_t).

The result is that reading from AssetInputStream is possible only by using read(byte[]) or read(byte[], int, int).

OTHER TIPS

you can read assets using 'int read()' method, try:

AssetManager mgr = getAssets();
try {
    InputStream is = mgr.open("test.txt");
    Log.d(TAG, "onCreate 'is': " + is);
    Log.d(TAG, "onCreate note 'is' is android.content.res.AssetManager$AssetInputStream");
    int c;
    while ((c = is.read()) != -1) {
        Log.d(TAG, "onCreate " + (char) c);
    }
} catch (IOException e) {
    e.printStackTrace();
}

and the output (for a file assets/test.txt which contains bytes "qwertyuiop" is:

D/Test ( 872): onCreate 'is': android.content.res.AssetManager$AssetInputStream D/Test ( 872): onCreate note 'is' is android.content.res.AssetManager$AssetInputStream D/Test ( 872): onCreate q D/Test ( 872): onCreate w D/Test ( 872): onCreate e D/Test ( 872): onCreate r D/Test ( 872): onCreate t D/Test ( 872): onCreate y D/Test ( 872): onCreate u D/Test ( 872): onCreate i D/Test ( 872): onCreate o D/Test ( 872): onCreate p

but as you did not provide the Uri you are using to create your AssetInputStream i cannot reproduce your exact error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top