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?
Android devices have not had built-in animated GIF support, which causes GIFs to load slower on some Android phones than on other OS.
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.
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.
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();
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With