Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Failing to load gif file using Movie class

I'm trying to use android.graphics.Movie to play a GIF file from /sdcard/download.

If I put the file in the drawable folder in the APK, I can load it using:

InputStream istr = context.getResources().openRawResource(R.drawable.animfile);
Movie movie = Movie.decodeStream(istr);

That works. movie.duration() will show the correct duration, which I use to derive the value for movie.setTime().

The problem happens if, instead of drawable, I try to load it from the sd-card using

String path = Environment.getExternalStorageDirectory() + "/download/animfile.gif";
Movie movie = Movie.decodeFile(path);

It seems to load something as movie isn't null. But the problem is that movie.duration() returns 0.

Any idea why this happens, and what I should be doing?

like image 629
aph Avatar asked May 15 '11 01:05

aph


People also ask

Why do some GIFs not work on Android?

Android devices have not had built-in animated GIF support, which causes GIFs to load slower on some Android phones than on other OS.

How do I view GIFs on my Android?

Android smartphones have a built-in image viewing application called Gallery. When you connect your Android smartphone to your computer and transfer a GIF file to your phone's storage area, you can open the Gallery appliation and view that GIF file.

How do I put GIFs on my Android?

We will use Glide Image loading & caching library to load Gif in Android. As we all now that directly we cannot load a Gif image in ImageView in Android. So mostly it's suggested to use Webview to load Gif images in Android. But I prefer to use the Glide library to load Gif in Android ImageView.


2 Answers

I ran into this as well. After much trial and error I got it to work using getContentResolver().openInputStream and the dead streamToBytes code in the android BitmapDecode example, which seems to work. I haven't come across an explanation yet as to why this needs to be done differently for package resources and sd files.

example:

...
Uri uri = Uri.parse(uriString);
java.io.InputStream is;
try {
    is = context.getContentResolver().openInputStream(uri);
}
catch(Exception e) {
}
byte[] array = streamToBytes(is);
Movie movie = Movie.decodeByteArray(array, 0, array.length);


private static byte[] streamToBytes(InputStream is) {
    ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
    byte[] buffer = new byte[1024];
    int len;
    try {
        while ((len = is.read(buffer)) >= 0) {
            os.write(buffer, 0, len);
        }
    } catch (java.io.IOException e) {
    }
    return os.toByteArray();
}
like image 85
jerarts Avatar answered Sep 27 '22 17:09

jerarts


You are right, except a one. You shouldn't use Uri and ContentResolver. Short solution is that you should use

Movie.decodeByteArray(array, 0, array.length)

instead of

Movie.decodeFile(path);

clue is in reset() method implementation of some stream that created inside the decodeFile(path) method.

like image 34
rus1f1kat0r Avatar answered Sep 27 '22 18:09

rus1f1kat0r