6

I have an app that shows GIF images. It all works fine if image is saved in drawable, and I access it like this

is=context.getResources().openRawResource(R.drawable.mygif);
movie = Movie.decodeStream(is);

But I need to download image from internet, so I'm saving it to CacheDir, that works fine. I tried the following to read it.

    try
    {
        is = new BufferedInputStream(new FileInputStream(new File(context.getCacheDir(), "mygif.gif")));
    }
    catch (FileNotFoundException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    movie = Movie.decodeStream(is);

And this

movie = Movie.decodeFile(new File(context.getCacheDir(), "mygif.gif").getPath());

But no matter what, it ends with

java.io.IOException
at java.io.InputStream.reset(InputStream.java:218)
at android.graphics.Movie.decodeStream(Native Method)
at android.graphics.Movie.decodeTempStream(Movie.java:74)
at android.graphics.Movie.decodeFile(Movie.java:59)

or

java.io.IOException: Mark has been invalidated.
at java.io.BufferedInputStream.reset(BufferedInputStream.java:350)
at android.graphics.Movie.decodeStream(Native Method)

I think it's a very simple error, but I can't get over it. Manifest has:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4

4 に答える 4

14

suggestion:

1.try move the download location to another folder like: sdcard, or the app another folder except the cache.

2.when init the inputstream, try use: init with a buffer size

int buffersize = 16*1024;
InputStream  is = new BufferedInputStream(xxx,buffersize);

3.to check the file existed in your folder

update: change the code like this and dont use Movie.decodeFile

 InputStream is = null;
    try {
        is = new BufferedInputStream(new FileInputStream(new File(getCacheDir(), "mygif.gif")), 16 * 1024);
        is.mark(16 * 1024); 
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
movie = Movie.decodeStream(is);

no exception throw, and the movie is not null.

Also, although your code will throw the exception, the movie is also not null.

于 2012-04-20T05:38:22.233 に答える
2

I know is a really old post, but I was having the same issue

Copying the InputStream to a byte array and calling Movie.decodeByteArray worked for me, even on Samsung Devices

于 2014-10-06T17:40:36.870 に答える
0

My answer is based on the BeNeXuS's answer.

The file size may not always be known, see:

File file = ...;
InputStream inputStream = new FileInputStream(file);

or

InputStream inputStream = getContext().getContentResolver().openInputStream(uri);

After getting the inputStream:

BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte buffer[] = new byte[1024];
int len;
while ((len = bis.read(buffer, 0, buffer.length)) > 0) {
    baos.write(buffer, 0, len);
}
bis.close();

byte[] imageData = baos.toByteArray();
baos.close();

Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
于 2015-08-18T16:35:11.657 に答える
0

Android up to 4.4 fails to decode Movie from File and Stream in case of internal IOException in InputStream.reset() method. But decoding from bytes works well on all versions of Android. Here is quite minimal version of code to do this:

int size = (int) imageFile.length();
byte[] buffer = new byte[size];
FileInputStream inputStream = new FileInputStream(imageFile);
int readLength = inputStream.read(buffer);
inputStream.close();
Movie movie = Movie.decodeByteArray(buffer, 0, readLength);
于 2016-04-04T10:56:26.197 に答える