web-dev-qa-db-fra.com

Prendre une photo de la caméra en fragment

Dans ma Fragment, j'essaie de prendre une photo de mon appareil photo, mais la onActivityResult de ma Fragment n'est pas appelée. Après avoir pris une photo, cette Fragment n'est pas affichée et passe à ma première Fragment. Y at-il un autre moyen de capturer des photos dans une Fragment ou que fais-je de travers?

Voici mon code actuel:

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());
                }
            }
        }
    }
18
user2106897

J'ai essayé votre code son travail bien mec. j'ai changé 

PhotosListFragment.this.startActivityForResult(intent, 100);

à

getActivity().startActivityForResult(intent, 100);

qui après avoir pris la photo, retournant à la même activité.

Je pense que vos deux fragments sont sur la même activité.

si tel est le cas, je vous suggère de créer une nouvelle activité et d'y insérer le nouveau fragment.

7
Amitabh Sarkar

J'espère que ceci vous aidera:

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

            }
        }        
    }    
}
20
Sanjay Mangaroliya

C'est l'un des problèmes les plus populaires. Nous pouvons trouver beaucoup de discussions sur ce problème. Mais aucun d'entre eux n'est utile pour moi. 

J'ai donc résolu ce problème en utilisant cette solution.

Voyons d'abord pourquoi cela se produit.

Nous pouvons appeler startActivityForResult directement à partir de Fragment mais, en réalité, le mécanicien derrière est géré par activité.

Une fois que vous appelezstartActivityForResultdepuis un fragment, requestCode sera modifié pour attacher l'identité du fragment au code. Cela permettra à Activity de retracer ceux qui envoient cette demande une fois le résultat reçu.

Une fois l'activité retrouvée, le résultat sera envoyé à onActivityResult d'Activity avec le requestCode modifié qui sera décodé en identifiant le requestCode + identité d'origine. Après cela, Activity enverra le résultat de l'activité à ce fragment via onActivityResult. Et tout est fait.

Le problème est:

Activity pourrait envoyer le résultat uniquement au fragment qui a été attaché directement à Activity mais pas au fragment imbriqué. C'est la raison pour laquelle onActivityResult de fragment imbriqué n'a jamais été appelé quoi qu'il arrive.

Solution:  

1) Lancez l'objectif de l'appareil photo dans votre fragment à l'aide du code ci-dessous:

       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) Maintenant, dans votre activité parent, remplacez ** onActivityResult(): **

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

Vous devez appeler cela dans l'activité parent pour que cela fonctionne.

3) Dans votre fragment appel:

@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) Méthodes de référence pour obtenir l'URI:

-> Méthode d'obtention d'Uri à partir du bitmap

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

-> Méthode d'obtention du chemin du fichier depuis l'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();
            }
        }
    }

C'est ça… .. Avec cette solution, elle pourrait être appliquée à n'importe quel fragment, qu'il soit imbriqué ou non. Et oui, cela couvre aussi tous les cas! De plus, les codes sont aussi gentils et propres.

11
KishuDroid

Pour Fragment c'est la solution la plus simple: 

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

    }
}
0
Paras BK