Фотосъемка с камеры в фрагменте

В моем 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());
                }
            }
        }
    }

Ответы

Ответ 1

Я пробовал свой код, работая прекрасным чуваком. Я изменил

PhotosListFragment.this.startActivityForResult(intent, 100);

к

getActivity().startActivityForResult(intent, 100);

который после съемки, возвращаясь к той же активности.

Я думаю, что оба ваших фрагмента находятся в одной и той же активности.

если это так, я предлагаю вам создать новую активность и разместить там новый фрагмент.

Ответ 2

Надеюсь, это поможет вам:

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);

            }
        }        
    }    
}

Ответ 3

Это одна из самых популярных проблем. Мы можем найти много сообщений об этой проблеме. Но ни один из них не полезен для меня.

Итак, я решил эту проблему, используя это решение.

Позвольте сначала понять, почему это происходит.

Мы можем вызвать startActivityForResult непосредственно из Fragment, но на самом деле механика позади обрабатываются Activity.

Как только вы вызываете startActivityForResult из фрагмента, requestCode будет изменен, чтобы привязать идентификатор фрагмента к коду. Это позволит Activity отслеживать, кто отправляет этот запрос после получения результата.

После того, как операция была перенесена обратно, результат будет отправлен в Activity onActivityResult с измененным кодом запроса, который будет декодирован до исходного идентификатора requestCode + Fragment. После этого Activity отправит результат активности на этот фрагмент через onActivityResult. И все это сделано.

Проблема заключается в следующем:

Активность может отправить результат только фрагменту, который был прикреплен непосредственно к Activity, но не к вложенному. Причина, по которой 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();
            }
        }
    }

Что это. С помощью этого решения он может применяться для любого отдельного фрагмента, независимо от того, является он вложенным или нет. И да, это также охватывает весь случай! Кроме того, коды также приятны и чисты.

Ответ 4

Для фрагмента это простейшее решение:

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();

    }
}