Android - Не удается загрузить GIF-файл с помощью класса Movie - PullRequest
5 голосов
/ 15 мая 2011

Я пытаюсь использовать android.graphics.Movie для воспроизведения файла GIF из /sdcard/download.

Если поместить файл в папку drawable в APK, я могу загрузить его с помощью:

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

Это работает. movie.duration() покажет правильную продолжительность, которую я использую для получения значения для movie.setTime().

Проблема возникает, если вместо рисования я пытаюсь загрузить его с SD-карты, используя

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

Кажется, что загружается что-то , поскольку movie не равно нулю. Но проблема в том, что movie.duration() возвращает 0.

Есть идеи, почему это происходит, и что мне следует делать?

Ответы [ 3 ]

3 голосов
/ 17 августа 2011

Я тоже столкнулся с этим. После долгих проб и ошибок я заставил его работать, используя getContentResolver (). OpenInputStream и мертвый код streamToBytes в примере Android BitmapDecode , который, кажется, работает. Я еще не сталкивался с объяснением того, почему это нужно делать по-разному для ресурсов пакета и файлов SD.

пример:

...
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();
}
2 голосов
/ 01 сентября 2011

Вы правы, кроме одного.Вы не должны использовать Uri и ContentResolver.Короткое решение состоит в том, что вы должны использовать

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

вместо

Movie.decodeFile(path);

. Подсказка в реализации метода reset () некоторого потока, созданного внутри метода decodeFile (path).

1 голос
/ 21 августа 2012
 is = new FileInputStream(file path);



                if (path != null) {
                            try {
                                byte[] array = streamToBytes(is);
                                mMovie =  Movie.decodeByteArray(array, 0, array.length);

                                mDuration = mMovie.duration();
                                Log.v("total time ", mDuration + "");
                            } finally {
                                is.close();
                            }
                        } else {
                            throw new IOException("Unable to open R.raw.");
                        }


 private 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();
            }
...