【问题标题】:Android cooliris gallery developer documentationAndroid cooliris 图库开发者文档
【发布时间】:2011-01-15 09:01:24
【问题描述】:

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

谢谢。

【问题讨论】:

  • 我认为有办法做到这一点。让我调查一下。
  • 找到解决办法了吗?

标签: android image gallery cooliris


【解决方案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 类查询)。

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

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

【讨论】:

  • 不幸的是,这对我不起作用。它显示了我手机上一些随机照片的文件夹。诚然,我可能错误地执行了您的答案。我设法找到了一个足够接近的解决方案,我会发布给其他感兴趣的人。
  • 查看我上面的编辑,写你足够接近的解决方案和持续的问题。
  • 好的,我按照你描述的方式重新设计了一些东西。 onMediaScannerConnected 方法启动了这个过程的其余部分,它运行得非常好。非常感谢!我仍然无法让 bucketId 工作。在模拟器上它看起来像是在工作,但在我的手机上它一直在打开一个不同的文件夹。只是为了确保我执行了一个查询来获取第一个图像 Uri 的 BUCKET_ID 并且仍然得到了错误的文件夹。哦,好吧,我可以没有它。
  • 我有 "Log.e(TAG, "Error found album" + bucketId);",但我的 bucketId 是正确的
  • 不,抱歉。我继续前进。
【解决方案2】:

我也尝试了 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源码问题吗?

【讨论】:

  • 您找到解决方案了吗? ?
【解决方案3】:

是的。是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);之后的循环中会解决问题,但没人会这样做。

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

【讨论】:

  • DataInputStream 类型的方法 getBoolean() 未定义。我该如何解决?谢谢
【解决方案4】:

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

这是我想要完成的任务的描述。用户从列表视图中选择特定记录。该记录可以有一些与之关联的图像。我希望能够使用 Nexus One 上酷炫的 Gallery3D 应用程序浏览这些图像(现在具有多点触控缩放功能!)。如果该记录的图像尚未缓存在设备的 SD 卡上,我会将它们下载为 zip 文件。然后我将该文件提取到 sdcard 上该记录的缓存目录。之后,我想启动图库并仅显示该缓存目录中的图像。

执行下载并将 zip 文件解压缩到 sdcard 没有问题。但是,为了让画廊正常工作,我不得不将 MediaScannerConnection 与 MediaScannerConnectionClient 一起使用。在让扫描仪连接后(这有点像 flakey),我遍历了缓存目录中调用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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    相关资源
    最近更新 更多