2

有谁知道如何与新的 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

4 回答 4

1

是的。是源代码问题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);将解决问题,但没有人会这样做。

因此,很明显,由于源代码中的错误,无法在 Gallery 中显示指定的存储桶(目录)。:(

于 2011-11-11T20:29:38.987 回答
1

我被告知你需要像这样启动它:

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);

更多信息:

确保您有正确的路径(检查斜杠等)。作为测试,您可以检查从您的方法中得出的存储桶 id 是否等于数据库中的存储桶 id(您可以使用 MediaProvider 类查询)。

您现在正在做的是传递该存储桶中的第一张图像,画廊会自动显示其他图像,但不同之处在于您正在尝试查看图像,而不是存储桶,这就是它不显示的原因在缩略图视图中。

就您的 MediaScanner 问题而言, connect() 是一个异步调用,因此您应该在实现 MediaScannerConnectionClient 接口的方法 onMediaScannerConnected 中执行所有操作。您已经为 onScanCompleted 实现了此接口,因此您只需将逻辑放在那里,而不是轮询 MediaScannerService 以查看它是否已连接。

于 2010-02-10T20:43:23.490 回答
1

我也尝试了 Jeff 的代码。看来它只适用于旧画廊而不是新的画廊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);
    }

而且由于我收到“查找专辑时出错”错误,而不是“找不到专辑 ID 的专辑”,这意味着 android 正在查找专辑,但在这些行的某处遇到了 IOException。那么这是一个android源问题吗?

于 2010-04-18T22:00:09.547 回答
0

我无法获得工作文件夹的缩略图视图。相反,我通过在文件夹中的第一张图像上启动画廊来管理几乎一样好的东西。

这是我想要完成的描述。用户从列表视图中选择特定记录。该记录可以有一些与之关联的图像。我希望能够使用 Nexus One 上酷炫的 Gallery3D 应用程序浏览这些图像(现在具有多点触控缩放功能!)。如果该记录的图像尚未缓存在设备的 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!");
}

丑我知道,但我不确定为什么第一次连接有问题。:-/

更新:感谢 jeffamaphone,我能够转储那些丑陋的代码。现在 OnItemClickListener 只需调用scanner.connect()。传递给扫描仪构造函数的客户端初始化 DownloadAsyncTask,它在解压缩文件并调用scanner.scanFiles(...) 时更新ProgressDialog;

于 2010-02-10T22:19:37.480 回答