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"/>
Bojan Kogoj
  • 5,321
  • 3
  • 35
  • 57
  • You should test whether the download-and-save part is corrupting the file. After the app downloads the file, you can pull it off the emulator or device using `adb pull `. Then you can check whether it's exactly what's on the server. – Ted Hopp Apr 20 '12 at 04:03
  • I pulled it off emulator, and it's fine. Image is 13kB if that somehow is important – Bojan Kogoj Apr 20 '12 at 04:14
  • Have you tried `Movie.decodeFile(new File(context.getCacheDir(), "mygif.gif").getAbsolutePath())`? – Ted Hopp Apr 20 '12 at 04:19
  • It doesn't help, I still get the error. – Bojan Kogoj Apr 20 '12 at 04:27

4 Answers4

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.

idiottiger
  • 5,147
  • 2
  • 25
  • 21
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

BeNeXuS
  • 497
  • 5
  • 11
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);
NikitaFeodonit
  • 165
  • 1
  • 10
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);
Roman
  • 121
  • 3