1. ホーム
  2. android

[解決済み] ギャラリー(SDカード)からアプリに使用する画像を選ぶには?

2022-03-16 03:08:55

質問

この質問は、もともとAndroid 1.6で出題されたものです。

アプリの写真オプションに取り組んでいます。

私のアクティビティには、ボタンとImageViewがあります。ボタンをクリックすると、ギャラリーにリダイレクトされ、画像を選択することができます。選択された画像はImageViewに表示されます。

どのように解決するのですか?

約5年後に更新された回答です。

様々なソースからの画像が異なるコンテンツURIで返されることがあるため、元の回答にあるコードはもはや確実に動作しません。 content:// ではなく file:// . より良い解決策は、単純に context.getContentResolver().openInputStream(intent.getData()) これはInputStreamを返すので、好きなように処理することができます。

例えば BitmapFactory.decodeStream() オプションと inSampleSize フィールドを使用して、大きな画像をダウンサンプリングし、メモリの問題を回避することもできますので、この状況では完璧に機能します。

しかし、Google Driveなどは、実際にはまだダウンロードされていない画像へのURIを返します。そのため、getContentResolver()のコードはバックグラウンドスレッドで実行する必要があります。


オリジナルの回答です。

他の回答では、インテントの送信方法については説明されていましたが、レスポンスの処理方法についてはうまく説明されていませんでした。その方法について、サンプルコードを紹介します。

protected void onActivityResult(int requestCode, int resultCode, 
       Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 

    switch(requestCode) { 
    case REQ_CODE_PICK_IMAGE:
        if(resultCode == RESULT_OK){  
            Uri selectedImage = imageReturnedIntent.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};

            Cursor cursor = getContentResolver().query(
                               selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String filePath = cursor.getString(columnIndex);
            cursor.close();


            Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath);
        }
    }
}

この後、選択した画像を"yourSelectedImage"に格納し、好きなように使えるようにします。このコードは、ContentResolverデータベース内の画像の位置を取得することで動作しますが、それだけでは十分ではありません。各画像には、ファイルパスから「最終更新日」、撮影場所のGPS座標まで、約18列の情報がありますが、多くのフィールドは実際には使用されていません。

他のフィールドは実際に必要ないので時間を節約するために、カーソル検索はフィルターを使って行われます。フィルタは、必要な列の名前、MediaStore.Images.Media.DATA、つまりパスを指定し、その文字列[]をカーソル クエリに与えることで動作します。カーソルクエリはパスとともに返されますが、どのカラムにあるのかは columnIndex というコードがあります。これは単に名前に基づいて列の番号を取得するもので、フィルタリング処理で使用されるものと同じものです。これができたら、最後に紹介したコードでようやく画像をビットマップにデコードできるようになります。