2

撮影したばかりの写真を取得できません。OnActivityResult、ケースCAPTURE_IMAGE_ACTIVITY_REQUEST_CODEに問題があると思います。ケース1でアルバムから写真を取得すると正常に機能します。親切なアドバイスをお願いします。

ソースコード:

    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
        super.onActivityResult(requestCode, resultCode, data); 
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
           if(resultCode == RESULT_OK){     
             Uri targetUri = (data != null) ? data.getData() : null;
             if (targetUri == null) {
                 targetUri = fileUri;
             }
             imageView.setImageURI(targetUri);
           }
           if(resultCode == RESULT_CANCELED){   
             Uri targetUri = (data != null) ? data.getData() : null;
             if (targetUri == null) {
                 targetUri = fileUri;
             }
             imageView.setImageURI(targetUri);
           }
           else{  ; 
             Uri targetUri = (data != null) ? data.getData() : null;
             if (targetUri == null) {
                 targetUri = fileUri;
             }
             imageView.setImageURI(targetUri);
           }
    }   
    else if(requestCode == 1) {
        if(resultCode == RESULT_OK){  
            Uri selectedImage = data.getData();
            imageView.setImageURI(selectedImage);
        }
    }
}

}

4

3 に答える 3

2

画像を取得できるかどうかは、残念ながら電話の製造元によって異なります。すべてのAndroidバージョンとすべてのメーカーはわずかに異なる動作をしているようです。URLが「データ」パラメーターとして結果に提供される場合もありますが(これが実行していることです)、空の場合もあります。それは完全に機能しましたが、RESULT_CANCELを返す電話を一度も手に入れました。

あらゆる種類の異なるフォールバックを実装する方法はないようです。これが私が現在私たちのプロジェクトの1つで使用している私のコードです。メンバー変数は、インテントパラメータとしてmTargetUri指定した出力ファイル名に設定する必要があります。インテントを起動する直前に設定する必要があります。MediaStore.EXTRA_OUTPUTmCaptureTimeSytem.currentTimeMillis()

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            Log.v(LOG_TAG, "Camera intent succeeded");
        }
        else if (resultCode == RESULT_CANCELED) {
            Log.i(LOG_TAG, "Camera intent aborted");
        }
        else {
            Log.e(LOG_TAG, "Camera intent failed with result code: " + resultCode);
        }

        // Regardless of the resultCode we're going to check if a new photo has been
        // created on the phone. At least on the Samsung Galaxy S3 the behavior
        // could be observed that although the result code was "0" the camera app
        // created two (!) files on the SD card.

        // Image captured and saved to fileUri specified in the Intent
        Uri targetUri = (data != null) ? data.getData() : null;
        if (targetUri == null) {
            Log.w(LOG_TAG, "Camera intent returned empty result.");
            targetUri = mTargetUri;
        }

        if (targetUri != null) {
            String targetFilePath = targetUri.getPath();
            File targetFile = new File(targetFilePath);
            if (targetFile.exists()) {
                Log.i(LOG_TAG, "Image saved to: " + targetUri.toString());

                // Fix for issue reported here: http://code.google.com/p/android/issues/detail?id=22822
                // and here: http://code.google.com/p/android/issues/detail?id=19268
                // We're following the proposed solution from https://stackoverflow.com/questions/8450539/
                int rotation = -1;
                long fileSize = targetFile.length();
                Cursor mediaCursor = getContentResolver().query(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
                        new String[] { 
                            MediaStore.Images.ImageColumns.ORIENTATION, 
                            MediaStore.MediaColumns.SIZE,
                            MediaStore.MediaColumns.DATA }, 
                        MediaStore.MediaColumns.DATE_ADDED + ">=?", 
                        new String[] { String.valueOf(mCaptureTime/1000 - 1)}, 
                        MediaStore.MediaColumns.DATE_ADDED + " desc");

                if ((mediaCursor != null) && (mCaptureTime != 0)) {
                    if (mediaCursor.moveToFirst()) {
                        do {
                            long size = mediaCursor.getLong(1);
                            Uri uri = Uri.parse(mediaCursor.getString(2));
                            // Extra check to make sure that we are getting the orientation from the proper file
                            if (size == fileSize && !uri.equals(targetUri.toString())) {
                                rotation = mediaCursor.getInt(0);
                                break;
                            }
                        } while (mediaCursor.moveToNext());
                    }
                    mediaCursor.close();
                }

                if (rotation == -1) {
                    // It seems that there has been no duplication and no rotation issue so far. This means we can
                    // add our newly created file to the media library.
                    // TODO
                }
                else {
                    // Looks like the picture already exists in the media library. This indicates we got a duplicate.
                    Log.w(LOG_TAG, "Duplicate image found for " + targetUri.toString() + " in media library. Deleting the copy.");
                    if (!targetFile.delete()) {
                        Log.e(LOG_TAG, "Failed to delete duplicate image.");
                    }
                }
            }
            }
    }
}

このコードは、Stackoverflowや他のサイトのさまざまなソースから発信されています。基本的な考え方は、

  1. 結果コード(RESULT_OKまたはRESULT_CANCELED)は、写真が撮影されてSDカードに保存されたかどうかを示すものではないため、無視してください。上記のコードは値をログに記録するだけですが、どのような場合でも続行します。
  2. 次に、インテント結果によって提供されたURIがあったかどうかを確認します。URIを取得した場合、それが実際に新しく撮影された写真を指していると想定するのが安全です。ただし、すべてが完全に成功したにもかかわらず、そのようなURIを取得することはできません。この場合を処理するには、カメラアクティビティに最初に提供したURI(mTargetUri)を使用して、そこに新しいファイルが見つかることを期待します。
  3. 一部の新しいデバイスでは、カメラアプリが自動的に新しい写真をメディアライブラリに追加し、で最初に指定した方法で2番目のコピー名を作成しますtargetUri。このアプローチの問題は、画像が重複してしまうことです。これに対処するために、次のStackoverflowの質問から派生したロジックに従います。ACTION_IMAGE_CAPTUREで撮影された画像は、一部の新しいデバイスではExifInterface.TAG_ORIENTATIONに対して常に1を返します。ここでは詳細については説明しませんが(リンクをたどって理解を深めるだけです)、基本的な考え方は、Androidメディアストアにクエリを実行し、タイムスタンプを比較して新しい写真が既に含まれているかどうかを確認することですmCaptureTimeSystem.currentTimeMillis()キャプチャインテントは元々開始されました)。
  4. メディアストアでエントリが見つかった場合は、重複を削除するだけです。

このロジックは、事実上すべてのAndroidデバイスですべての場合に機能するはずです。これまでのところ、追加の問題なしに、数十の異なるデバイスとAndroidバージョンでテストしました。

于 2012-11-09T19:23:32.927 に答える
2

同じ問題に直面しました。チェックしたら、履歴に関連するタグを付けましたか?

android:noHistory="true"マニフェストにタグを付けないでください

android:noHistory="true"マニフェスト内のアクティビティで使用する場合、停止後にスタックから削除されます。

注:タブアクティビティを使用している場合は、使用しないでくださいandroid:noHistory="true"

または、android:noHistory="false"マニフェスト内にアクティビティを配置するだけです。

于 2013-07-03T10:47:35.137 に答える
0

カメラを向けて、ランドスケープモードで写真を撮ってみてください。MediastoreCameraIntentは風景写真のみを撮影しているようです。

于 2012-11-27T08:11:26.577 に答える