5

私のアプリでは、次のように、ユーザーがギャラリーからプロフィール画像を選択できるようにします。

ここに画像の説明を入力

私の Android 5.0 デバイスで最初のオプションをクリックすると、次のようになります。

ここに画像の説明を入力

AOSP プロジェクトに基づく通常のギャラリー アプリを使用すると、すべてがうまく機能します。ただし、写真のアプリは別の意図を使用しているようです。

通常のギャラリーのコードを処理する方法は次のとおりです。

Intent photoPickerIntent = new Intent(
                    Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            photoPickerIntent.setType("image/*");
            photoPickerIntent.putExtra("crop", "true");
            photoPickerIntent.putExtra("outputX", 300);
            photoPickerIntent.putExtra("outputY", 300);
            photoPickerIntent.putExtra("aspectX", 1);
            photoPickerIntent.putExtra("aspectY", 1);
            photoPickerIntent.putExtra("scale", true);
            photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
            photoPickerIntent.putExtra("outputFormat",
                    Bitmap.CompressFormat.JPEG.toString());
            startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);

そして、インテント結果ハンドラー:

public void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == RESULT_LOAD_IMAGE
            && resultCode == Activity.RESULT_OK) {

        if (data != null) {

            tempFile = getTempFile();

            filePath = Environment.getExternalStorageDirectory() + "/"
                    + "temporary_holder.jpg";
            Log.d("LOAD REQUEST filePath", filePath);

            Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
            iPP.setImageBitmap(selectedImage);

        }

        imagePath = filePath;
        new UploadImage().execute();
    }
}

上記のヘルパー関数の一部:

   private static Uri getTempUri() {
        return Uri.fromFile(getTempFile());
    }

    private static File getTempFile() {

        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {

            File file = new File(Environment.getExternalStorageDirectory(),
                    "temporary_holder.jpg");
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return file;
        }
        return null;
    }

その一部はおそらく表示する必要はありませんが、干渉する場合に備えてすべて含めました.

Google フォトを使用して写真を選択すると、ImageView が空白になります (選択したピックで埋めるのではなく)。画像が選択されておらず、ギャラリーで設定したように手動トリ​​ミング ビューに移動できません。 したがって、基本的には何も起こりません。


回答に対する新しいコード

        photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
        photoPickerIntent.setType("image/*");
        photoPickerIntent.putExtra("crop", "true");
        photoPickerIntent.putExtra("outputX", 300);
        photoPickerIntent.putExtra("outputY", 300);
        photoPickerIntent.putExtra("aspectX", 1);
        photoPickerIntent.putExtra("aspectY", 1);
        photoPickerIntent.putExtra("scale", true);
        photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
        photoPickerIntent.putExtra("outputFormat",
                Bitmap.CompressFormat.JPEG.toString());
        startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);



public void onActivityResult(int requestCode, int resultCode, Intent data) {



    if (resultCode == Activity.RESULT_OK) {

        if (data != null) {

            Log.i("data", data.toString());

            switch (requestCode) {

                case RESULT_LOAD_IMAGE:

                    Log.i("RESULT_LOAD_IMAGE", "MARK");
                    // Received an image from the picker, now send an Intent for cropping
                    final String CROP_ACTION = "com.android.camera.action.CROP";
                    Intent photoCropIntent = new Intent(CROP_ACTION);
                    photoCropIntent.putExtra("crop", "true");
                    photoCropIntent.putExtra("aspectX", 1);
                    photoCropIntent.putExtra("aspectY", 1);
                    photoCropIntent.putExtra("outputX", 300);
                    photoCropIntent.putExtra("outputY", 300);
                    photoCropIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
                    photoCropIntent.putExtra("outputFormat",
                            Bitmap.CompressFormat.JPEG.toString());
                    photoCropIntent.setData(data.getData());

                    startActivityForResult(photoPickerIntent, RESULT_CROP_IMAGE);

                    break;

                case RESULT_CROP_IMAGE:

                    Log.i("RESULT_CROP_IMAGE", "MARK");

                    tempFile = getTempFile();
                    imagePath = Environment.getExternalStorageDirectory() + "/"   + "temporary_holder.jpg";
                    Log.i("imagePath", imagePath);

                    Uri selectedImageURI = data.getData();
                    InputStream image_stream;
                    try {
                        image_stream = getActivity().getContentResolver().openInputStream(selectedImageURI);
                        Bitmap bitmap = BitmapFactory.decodeStream(image_stream);
                        iPP.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    new UploadImage().execute();

                    break;

                default:
                    // Handle default case
            }
        }

    }

}

上記のコードも機能しません。以下の答えに似せようとしました。何が起こるか:

「ギャラリーから選択」をクリックします。ストックギャラリーから直接開くようになりました(大したことではありません)。画像をクリックすると、... 同じことが最初からintentやり直されるように見えます - ギャラリーが戻ってきて、別の画像を選択するように求められます: 切り抜き の代わりにActivity。2回目以降はImageView、選択したファイルで設定されます。

4

2 に答える 2

5

解決

photoPickerIntentまず、を useに更新し、ACTION_GET_CONTENTクロッピングに関連するエクストラを削除します。クロッピングはIntent後で別の処理を行うためです。

        Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
        photoPickerIntent.setType("image/*");
        // Do not include the extras related to cropping here;
        // this Intent is for selecting the image only.
        startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);

次に、onActivityResult()2 つの結果を処理する必要がありますRESULT_LOAD_IMAGE。クロップ用に別のインテントを送信し、RESULT_CROP_IMAGE以前と同様に処理を続行します。

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (data != null) {
                switch (requestCode) {
                case RESULT_LOAD_IMAGE:
                    // Received an image from the picker, now send an Intent for cropping
                    final String CROP_ACTION = "com.android.camera.action.CROP";
                    Intent photoCropIntent = new Intent(CROP_ACTION);
                    photoCropIntent.setData(data.getData());

                    // TODO: first get this running without extras, then test each one here
                    startActivityForResult(photoCropIntent, RESULT_CROP_IMAGE);
                    break;
                case RESULT_CROP_IMAGE:
                    // Received the cropped image, continue processing.  Note that this 
                    // is just copied and pasted from your question and may have 
                    // omissions.
                    tempFile = getTempFile();

                    filePath = Environment.getExternalStorageDirectory() + "/"
                            + "temporary_holder.jpg";
                    Log.d("LOAD REQUEST filePath", filePath);

                    Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
                    iPP.setImageBitmap(selectedImage);

                    imagePath = filePath;
                    new UploadImage().execute();
                    break;
                default:
                    // Handle default case
                }
            }
        }

このコードの一部はテストしましたが、実行時にこのコード ブロック全体をテストしていないことに注意してください。ただし、すぐに使用できない場合は、かなり近いはずです。質問や問題がある場合はコメントしてください。それに応じて回答を更新します。

バックグラウンド

AOSP Gallery2 ( com.android.gallery3d) と Photos の両方がインストールされた Android 5.0.1 (API 21) デバイスで、Intent. ギャラリーまたは写真のどちらかを選択するように求められました。

Photos を選択すると、ピッカーが表示され、画像を選択しました。Activityトリミング オプションなしで、すぐに に戻りました。

ギャラリーを選択すると、ピッカーが表示され、画像を選択しました。次に、トリミング用のアプリを選択するように求められました。 写真とギャラリーの両方がトリミングのオプションとして提示されました。

ギャラリーを選択したときの興味深いログ出力は次のとおりです。

// Send the Intent
3-07 15:20:10.347      719-817/? I/ActivityManager﹕ Displayed android/com.android.internal.app.ResolverActivity: +127ms

// Choose Gallery
03-07 15:20:27.762      719-735/? I/ActivityManager﹕ START u0 {act=android.intent.action.PICK typ=image/* flg=0x3000000 cmp=com.android.gallery3d/.app.GalleryActivity (has extras)} from uid 10084 on display 0
// (fixing highlighting after MIME type on previous line) */
03-07 15:20:27.814  22967-22967/? W/GalleryActivity﹕ action PICK is not supported
03-07 15:20:27.814  22967-22967/? V/StateManager﹕ startState class com.android.gallery3d.app.AlbumSetPage
03-07 15:20:27.967      719-817/? I/ActivityManager﹕ Displayed com.android.gallery3d/.app.GalleryActivity: +190ms

// Pick an image
3-07 15:21:45.993  22967-22967/? V/StateManager﹕ startStateForResult class com.android.gallery3d.app.AlbumPage, 1
03-07 15:21:46.011  22967-22967/? D/AlbumPage﹕ onSyncDone: ********* result=0
03-07 15:21:46.034  22967-24132/? I/GLRootView﹕ layout content pane 1080x1701 (compensation 0)
03-07 15:21:48.447     719-1609/? I/ActivityManager﹕ START u0 {act=com.android.camera.action.CROP dat=content://media/external/images/media/1000 flg=0x2000000 cmp=android/com.android.internal.app.ResolverActivity (has extras)} from uid 10100 on display 0

まず、注意してくださいW/GalleryActivity﹕ action PICK is not supported。なぜそれが機能するのかはわかりませんが、Dianne Hackborn によると、「...廃止されたと考えるべきACTION_PICKです。最新のアクションはACTION_GET_CONTENT、はるかによくサポートされています...」 上記のソリューションでこれに対処しました。

ただし、良いニュースは、画像を選択した後、.putExtra("crop", "true");Gallery がIntentトリミングのために別の画像を送信するように見えることです。ログには、使用するアクションとデータが明確に示されます。

このクロッピング インテントをテストしたところ、以前と同様に、クロッピング用のアプリを選択するよう求められました。ここでも、Photos と Gallery の両方がオプションとして表示され、両方ともトリミング インターフェイスが表示されました。

Photos は によるトリミングをサポートしているようですがIntent、 でのトリミングに関連する余分なものを無視するだけですがACTION_PICK、Gallery はIntent画像を選択した後に別のものを送信して応答します。とにかく、作業クロッピングの詳細を持つことは、Intent上記の解決策につながります。

于 2015-03-07T07:19:53.150 に答える