22

私の中で私はFragment私のカメラから写真を撮ろうとしますが、onActivityResult私ののFragmentは呼ばれていません。写真を撮った後、これFragmentは表示されておらず、私の最初のものに切り替わりFragmentます。で写真をキャプチャする他の方法はありますかFragment、または私は何が間違っていますか?

これが私の現在のコードです:

public void takePhoto() {
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        File photo = new File(Environment.getExternalStorageDirectory(),  "Pic.jpg");
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(photo));
        imageUri = Uri.fromFile(photo);
        PhotosListFragment.this.startActivityForResult(intent, 100);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
        case 100:
            if (resultCode == Activity.RESULT_OK) {
                Uri selectedImage = imageUri;
                getActivity().getContentResolver().notifyChange(selectedImage, null);
                ContentResolver cr = getActivity().getContentResolver();
                Bitmap bitmap;
                try {
                     bitmap = android.provider.MediaStore.Images.Media
                     .getBitmap(cr, selectedImage);

                    viewHolder.imageView.setImageBitmap(bitmap);
                    Toast.makeText(getActivity(), selectedImage.toString(),
                            Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    Toast.makeText(getActivity(), "Failed to load", Toast.LENGTH_SHORT)
                            .show();
                    Log.e("Camera", e.toString());
                }
            }
        }
    }
4

4 に答える 4

25

これがお役に立てば幸いです。

public class CameraImage extends Fragment {

    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1888;
    Button button;
    ImageView imageView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        final View rootView = inflater.inflate(R.layout.camera_image,
                container, false);

        button = (Button) rootView.findViewById(R.id.button);
        imageView = (ImageView) rootView.findViewById(R.id.imageview);

        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent,
                        CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

            }
        });

        return rootView;

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {

                Bitmap bmp = (Bitmap) data.getExtras().get("data");
                ByteArrayOutputStream stream = new ByteArrayOutputStream();

                bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
                byte[] byteArray = stream.toByteArray();

                // convert byte array to Bitmap

                Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
                        byteArray.length);

                imageView.setImageBitmap(bitmap);

            }
        }        
    }    
}
于 2014-02-15T13:40:17.160 に答える
18

これは最も人気のある問題の1つです。この問題に関して多くのスレッドを見つけることができます。しかし、それらのどれも私にとって有用ではありません。

だから私はこの解決策を使用してこの問題を解決しました。

まず、なぜこれが起こっているのかを理解しましょう。

Fragmentから直接呼び出すことができますstartActivityForResultが、実際には背後のメカニックはすべてActivityによって処理されます。

フラグメントから呼び出すとstartActivityForResult、requestCodeが変更され、フラグメントのIDがコードに付加されます。これにより、Activityは、結果が受信されると、このリクエストを送信したユーザーを追跡できるようになります。

アクティビティが元に戻されると、結果はアクティビティのonActivityResultに送信され、変更されたrequestCodeが元のrequestCode+フラグメントのIDにデコードされます。その後、ActivityはonActivityResultを介してアクティビティ結果をそのフラグメントに送信します。そして、それはすべて完了しました。

問題は:

アクティビティは、アクティビティに直接アタッチされているフラグメントのみに結果を送信できますが、ネストされたフラグメントには送信できません。これが、ネストされたフラグメントのonActivityResultが何があっても呼び出されない理由です。

解決:

1)以下のコードでフラグメントのカメラインテントを開始します。

       Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
       Fragment frag = this;
       /** Pass your fragment reference **/
       frag.startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); // REQUEST_IMAGE_CAPTURE = 12345

2)親アクティビティのオーバーライド**onActivityResult():**

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

これを機能させるには、親アクティビティでこれを呼び出す必要があります。

3)フラグメント呼び出しで:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == REQUEST_IMAGE_CAPTURE) {
                // Do something with imagePath  

                Bitmap photo = (Bitmap) data.getExtras().get("data");
                imageview.setImageBitmap(photo);
                // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
                Uri selectedImage = getImageUri(getActivity(), photo);
                String realPath=getRealPathFromURI(selectedImage);
                selectedImage = Uri.parse(realPath);
            }    
       }
}

4)URIを取得するための参照メソッド:

->ビットマップからURIを取得する方法

 public Uri getImageUri(Context inContext, Bitmap inImage) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }

->URIからファイルパスを取得する方法

  public String getRealPathFromURI(Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = getActivity().getContentResolver().query(contentUri,  proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

それでおしまい。このソリューションでは、ネストされているかどうかに関係なく、任意の単一フラグメントに適用できます。そして、はい、それはすべての場合もカバーします!さらに、コードも素晴らしく、きれいです。

于 2016-09-01T08:46:15.477 に答える
8

私はあなたのコードをうまく機能させてみました。私が変更され

PhotosListFragment.this.startActivityForResult(intent, 100);

getActivity().startActivityForResult(intent, 100);

写真を撮った後、同じ活動に戻ります。

両方のフラグメントが同じアクティビティにあると思います。

そのような場合は、新しいアクティビティを作成して、そこに新しいフラグメントを配置することをお勧めします。

于 2013-03-14T11:54:52.587 に答える
1

フラグメントの場合、これは最も簡単な解決策です。

cameraIamgeView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent cameraIntent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            getActivity().startActivityFromFragment(PlaceOrderFragment.this, cameraIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
        }
    });

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
   // super.onActivityResult(requestCode, resultCode, data);
    try {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK && data != null) {

            Bitmap bmp = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream stream = new ByteArrayOutputStream();

            /*
            bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();

            // convert byte array to Bitmap

            Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
                    byteArray.length);
            */

            cameraIamgeView.setImageBitmap(bmp);

        }
    }
    }catch(Exception e){
        Toast.makeText(this.getActivity(), e+"Something went wrong", Toast.LENGTH_LONG).show();

    }
}
于 2016-04-22T06:32:30.613 に答える