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

次のように起動する必要があると言われています。

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

私もジェフのコードを試しました。古いギャラリーでのみ機能し、新しいギャラリー 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 に答える
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) の読み取りが欠落しています。2行を入れる

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

後のループでmediaSet.mName = Utils.readUTF(dis);問題は解決しますが、誰もそれをしません。

というわけで、明らかにソースコードのバグで指定したバケット(ディレクトリ)をGalleryに表示できません。:(

于 2011-11-11T20:29:38.987 に答える
0

フォルダのサムネイルビューを機能させることができませんでした。代わりに、フォルダー内の最初の画像でギャラリーを起動することで、ほぼ同じように優れたものを管理しました。

これが私が達成したかったことの説明です。ユーザーはリストビューから特定のレコードを選択します。このレコードには、いくつかの画像を関連付けることができます。Nexus OneのクールなGallery3Dアプリを使用してこれらの画像を閲覧できるようにしたかったのです(現在はマルチタッチズーム付きです!)。そのレコードの画像がデバイスのSDカードにまだキャッシュされていない場合は、zipファイルとしてダウンロードします。次に、そのファイルをSDカード上のそのレコードのキャッシュディレクトリに抽出します。その後、ギャラリーを起動して、そのキャッシュディレクトリ内の画像のみを表示したいと思いました。

ダウンロードを実行し、zipファイルをSDカードに抽出することは問題ではありませんでした。ただし、ギャラリーを機能させるには、MediaScannerConnectionClientでMediaScannerConnectionを使用する必要がありました。スキャナーを接続させた後(これは一種の不安定なものでした)、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を初期化します。DownloadAsyncTaskは、ファイルを解凍してscanner.scanFiles(...);を呼び出すときにProgressDialogを更新します。

于 2010-02-10T22:19:37.480 に答える