Документация разработчика галереи Android cooliris - PullRequest
2 голосов
/ 10 февраля 2010

Кто-нибудь знает, как интегрироваться с новым приложением Gallery3D (cooliris android gallery)? Я хочу запустить это приложение, чтобы оно отображало эскизы только для определенной папки.

Например, скажем, мое приложение загружает изображения с моего сервера и сохраняет их в папке на SD-карте (/ sdcard / myapp / image-cache / someid / *). Я хотел бы иметь возможность сделать что-то вроде следующего:

// within an activity
Uri uri = Uri.withAppendedPath(Media.EXTERNAL_CONTENT_URI, "myapp/image-cache/someid");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

Спасибо.

Ответы [ 4 ]

1 голос
/ 12 ноября 2011

Да. Это проблема источника в CacheService.loadMediaSets.

Источник:

public static final void loadMediaSets(final Context context, final MediaFeed feed, final DataSource source,
        final boolean includeImages, final boolean includeVideos, final boolean moveCameraToFront) {
    // We check to see if the Cache is ready.
    syncCache(context);
    final byte[] albumData = sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0);
    if (albumData != null && albumData.length > 0) {
        final DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(albumData), 256));
        try {
            final int numAlbums = dis.readInt();
            for (int i = 0; i < numAlbums; ++i) {
                final long setId = dis.readLong();
                final String name = Utils.readUTF(dis);
                final boolean hasImages = dis.readBoolean();
                final boolean hasVideos = dis.readBoolean();
                MediaSet mediaSet = feed.getMediaSet(setId);
                if (mediaSet == null) {
                    mediaSet = feed.addMediaSet(setId, source);
                } else {
                    mediaSet.refresh();
                }
                if (moveCameraToFront && mediaSet.mId == LocalDataSource.CAMERA_BUCKET_ID) {
                    feed.moveSetToFront(mediaSet);
                }
                if ((includeImages && hasImages) || (includeVideos && hasVideos)) {
                    mediaSet.mName = name;
                    mediaSet.mHasImages = hasImages;
                    mediaSet.mHasVideos = hasVideos;
                    mediaSet.mPicasaAlbumId = Shared.INVALID;
                    mediaSet.generateTitle(true);
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error loading albums.");
            sAlbumCache.deleteAll();
            putLocaleForAlbumCache(Locale.getDefault());
        }
    } else {
        if (DEBUG)
            Log.d(TAG, "No albums found.");
    }
}

Чтение (hasImages и hasVideos) из метаданных альбома отсутствует. Ввод двух строк

 dis.getBoolean(); 
   dis.getBoolean(); 

в цикле после mediaSet.mName = Utils.readUTF(dis); решит проблему, но никто не сделает этого.

Итак, очевидно, что из-за ошибки в исходном коде невозможно отобразить указанный сегмент (каталог) в Галерее. (

1 голос
/ 19 апреля 2010

Я тоже попробовал код Джеффа. похоже, что он работает только в старой галерее, а не в новой галерее 3D.

Gallery3D в настоящее время возвращает это в logcat:

E/CacheService(  503): Error finding album -280923911

и просматривая источник для CacheService, я нашел это:

    if (albumData != null && albumData.length > 0) {
        DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(albumData), 256));
        try {
            final int numAlbums = dis.readInt();
            for (int i = 0; i < numAlbums; ++i) {
                final long setId = dis.readLong();
                MediaSet mediaSet = null;
                if (setId == bucketId) {
                    mediaSet = feed.getMediaSet(setId);
                    if (mediaSet == null) {
                        mediaSet = feed.addMediaSet(setId, source);
                    }
                } else {
                    mediaSet = new MediaSet();
                }
                mediaSet.mName = Utils.readUTF(dis);
                if (setId == bucketId) {
                    mediaSet.mPicasaAlbumId = Shared.INVALID;
                    mediaSet.generateTitle(true);
                    return;
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error finding album " + bucketId);
            sAlbumCache.deleteAll();
            putLocaleForAlbumCache(Locale.getDefault());
        }
    } else {
        Log.d(TAG, "No album found for album id " + bucketId);
    }

И поскольку я получаю ошибку «Ошибка при поиске альбома» вместо «Альбом не найден для идентификатора альбома», это означает, что android находит альбом, но где-то в этих строках возникает исключение IOException. Это проблема с источником Android?

1 голос
/ 10 февраля 2010

Мне сказали, что вам нужно запустить его так:

Uri targetUri = Media.EXTERNAL_CONTENT_URI;
String folderPath = Environment.getExternalStorageDirectory().toString() + "/" + "testFolder";
int folderBucketId = folderPath.toLowerCase().hashCode();
targetUri = targetUri.buildUpon().appendQueryParameter("bucketId", folderBucketId).build();

Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

Дополнительная информация:

Убедитесь, что у вас правильный путь (проверьте косые черты и т. Д.). В качестве теста вы можете проверить, равен ли идентификатор сегмента, полученный из вашего метода, идентификатору блока в базе данных (который можно запросить с помощью класса MediaProvider).

То, что вы делаете сейчас, - это передача первого изображения в этом сегменте, и галерея автоматически показывает другие изображения в поле зрения, но разница в том, что вы пытаетесь просмотреть изображение, а не сегмент, поэтому оно не отображается. не отображается в виде миниатюр.

Что касается вашей проблемы MediaScanner, то connect () - это асинхронный вызов, поэтому вы должны делать все в методе onMediaScannerConnected в вашей реализации интерфейса MediaScannerConnectionClient. Вы уже реализовали этот интерфейс для onScanCompleted, поэтому вам просто нужно поместить туда логику, а не опрашивать MediaScannerService, чтобы увидеть, подключился ли он.

0 голосов
/ 11 февраля 2010

Мне не удалось получить эскиз для работающей папки. Вместо этого я справился почти с тем же успехом, запустив галерею для первого изображения в папке.

Вот описание того, чего я хотел достичь. Пользователь выбирает конкретную запись из списка. С этой записью может быть связано несколько изображений. Я хотел иметь возможность просматривать эти изображения с помощью классного приложения Gallery3D на Nexus One (теперь с мультисенсорным зумом!). Если изображения для этой записи еще не кэшированы на SD-карте устройства, я скачаю их в виде zip-файла. Затем я извлекаю этот файл в каталог кеша для этой записи на SDCard. После этого я хотел запустить галерею и отображать только изображения в этой директории кэша.

Выполнение загрузки и распаковки zip-файла на SDCard не было проблемой. Но чтобы заставить галерею работать, мне пришлось использовать MediaScannerConnection с MediaScannerConnectionClient. После подключения сканера (что было довольно странно) я перебрал все файлы в директории кеша, вызвав scanner.scanFile.

MediaScannerConnectionClient # onScanCompleted будет добавлять полученные URI к переменной-члену ArrayList. Когда весь процесс был закончен, я запускаю галерею, пропуская первый URI в этом списке. Это будет просматривать первое изображение в каталоге. Я бы предпочел просмотр миниатюр, но этого достаточно.

Мне не совсем комфортно с этим решением. Кажется, что MediaScannerConnection работает асинхронно, поэтому моя AsyncTask выполняет опрос / сон, чтобы проверить, завершено ли сканирование.

У кого-нибудь еще были проблемы с подключением MediaScannerConnection при первом вызове? Чтобы обойти это, я делаю что-то вроде:

MediaScannerConnection scanner = ...;
for (int attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {
  scanner.connect();
  if (scanner.isConnected()) { break; }
  else {
    try { Thread.sleep(5); }
    catch (Exception e){}
  }
}

if (!scanner.isConnected()) {
  throw new IllegalStateException("Unable to establish media scanner connection!");
}

Ужасно, я знаю, но я не уверен, почему возникают проблемы с подключением в первый раз. : - /

UPDATE: Благодаря jeffamaphone я смог сбросить этот уродливый код. Теперь OnItemClickListener просто вызывает scanner.connect (). Клиент, который передается в конструктор сканера, инициализирует DownloadAsyncTask, который обновляет ProgressDialog, когда он распаковывает файлы и вызывает scanner.scanFiles (...);

...