Android Cooliris Gallery 开发者文档

发布于 2024-08-21 19:33:07 字数 398 浏览 7 评论 0原文

有谁知道如何与新的 Gallery3D 应用程序(cooliris android gallery)集成?我想启动该应用程序,以便它仅显示特定文件夹的缩略图。

例如,假设我的应用程序从服务器下载图像并将其存储在 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);

谢谢。

Does anyone know how to integrate with the new Gallery3D app (cooliris android gallery)? I want to launch that app so it shows the thumbnails for only a specific folder.

For example, say my app downloads images from my server and stores them in a folder on the sd-card (/sdcard/myapp/image-cache/someid/*). I'd like to be able to do something like the following:

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

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情徒 2024-08-28 19:33:07

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

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 来查看它是否已连接。

I'm told you need to launch it like this:

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

Further info:

Ensure that you have the right path (check trailing slashes etc). As a test, you can check if the bucket id that comes out from your method equals the bucket id in the database (which you can query for using the MediaProvider class).

What you are doing right now is passing the first image in that bucket, and gallery automatically shows other images in view, but the difference is that you are trying to view an image, not a bucket, which is why it doesn't show up in a thumbnail view.

As far as your MediaScanner issue goes, connect() is an async call, so you should do everything in the method onMediaScannerConnected in you implementation of the MediaScannerConnectionClient interface. You already implemented this interface for onScanCompleted, so you just need to put the logic there instead of polling the MediaScannerService to see if it has connected.

云裳 2024-08-28 19:33:07

我也尝试了杰夫的代码。看来它只适用于旧画廊,而不适用于新画廊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源码问题吗?

I tried Jeff's code as well. it appears that it only works in the old gallery and not in the new gallery3D.

Gallery3D is currently returning this in logcat:

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

and browsing the source for CacheService, I found this:

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

And since I'm getting the "Error finding album" error instead of the "No album found for album id", this means android is finding the album, but is running into an IOException somewhere in those lines. Is this then an android source problem?

写给空气的情书 2024-08-28 19:33:07

是的。这是 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)。 在 mediaSet.mName = Utils.readUTF(dis); 之后在循环中放入两行

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

可以解决问题,但没有人会这样做。

所以,显然,由于源代码中的错误,无法在 Gallery 中显示指定的存储桶(目录)。 :(

Yeah. It is source problem in the CacheService.loadMediaSets.

The source is:

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

Reading of (hasImages and hasVideos) from the album metadata is missing. Putting two lines

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

in the loop after mediaSet.mName = Utils.readUTF(dis); will solve the problem, but nobody will do it.

So, obviously, because of the bug in the source code it is impossible to display specified bucket (directory) in the Gallery. :(

就此别过 2024-08-28 19:33:07

我无法获得正在运行的文件夹的缩略图视图。相反,我通过在文件夹中的第一张图像上启动图库来完成几乎同样好的事情。

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

执行下载并将 zip 文件解压到 SD 卡上没有问题。但是,为了使图库正常工作,我必须将 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;

I wasn't able to get the thumbnail view for a folder working. Instead, I managed something almost as good by launching the gallery on the first image in the folder.

Here's a description of what I wanted to accomplish. A user selects a specific record from a list view. This record can have a few images associated with it. I wanted to be able to browse these images using the cool Gallery3D app on the Nexus One (now with multitouch zoom!). If the images for that record are not already cached on the device's sdcard I'll download them as a zip file. I then extract that file to a cache dir for that record on the sdcard. Afterwards, I wanted to launch the gallery and only display the images in that cache dir.

Performing the download and extracting the zip file to the sdcard was not a problem. But, in order to get the gallery working, I had to use the MediaScannerConnection with a MediaScannerConnectionClient. After getting the scanner to connect (which was kind of flakey), I looped through all the files in the cache dir calling scanner.scanFile.

The MediaScannerConnectionClient#onScanCompleted would append the resulting uri's to an ArrayList member variable. When the whole process was done I'd launch the gallery passing the first uri in that list. This would view the first image in the directory. I would've preferred the thumbnail view but this is good enough.

I'm not totally comfortable with this solution. It seems that the MediaScannerConnection works asynchronously so my AsyncTask does a poll/sleep to see if it's done scanning.

Has anyone else had issues with the MediaScannerConnection not connecting on the first call? To work around this I'm doing something like:

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!");
}

Ugly I know but I'm not sure why it has trouble connecting the first time. :-/

UPDATE:
Thanks to jeffamaphone, I was able to dump that ugly code. Now the OnItemClickListener just calls scanner.connect(). The client that is passed to the scanner's constructor initializes the DownloadAsyncTask which updates a ProgressDialog as it unzips the files and calls scanner.scanFiles(...);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文