Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Take photo from camera in fragment

Tags:

In my Fragment I try to take picture from my camera but the onActivityResult of my Fragment is not called. After taking photo this Fragment is not showing and is switching to my first Fragment. In there any other way for capturing photos in a Fragment, or what am I doing wrong?

Here is my current code:

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());                 }             }         }     } 
like image 934
user2106897 Avatar asked Mar 14 '13 11:03

user2106897


People also ask

How to get image from camera in Android programmatically?

This is done as follows: Intent camera_intent = new Intent(MediaStore. ACTION_IMAGE_CAPTURE); startActivityForResult(camera_intent, pic_id); Now use the onActivityResult() method to get the result, here is the captured image.

Is startActivityForResult deprecated?

onActivityResult , startActivityForResult , requestPermissions , and onRequestPermissionsResult are deprecated on androidx.

How to get camera access in Android Studio?

Just click on button present in the toolbar of Android Studio. Select your emulator. Now, your camera app is ready and displayed by the emulator. Now, when you click on camera in the app, your camera will start.

How to open camera in Android java?

Modify src/MainActivity. java file to add intent code to launch the Camera. Add the Camera permission and run the application and choose a running android device and install the application on it and verify the results. Following is the content of the modified main activity file src/MainActivity.


2 Answers

Hope this will help you:

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);              }         }             }     } 
like image 101
Sanjay Mangaroliya Avatar answered Sep 20 '22 10:09

Sanjay Mangaroliya


This is one of the most popular issue. We can found lots of thread regarding this issue. But none of them is useful for ME.

So I have solved this problem using this solution.

Let's first understand why this is happening.

We can call startActivityForResult directly from Fragment but actually mechanic behind are all handled by Activity.

Once you call startActivityForResult from a Fragment, requestCode will be changed to attach Fragment's identity to the code. That will let Activity be able to track back that who send this request once result is received.

Once Activity was navigated back, the result will be sent to Activity's onActivityResult with the modified requestCode which will be decoded to original requestCode + Fragment's identity. After that, Activity will send the Activity Result to that Fragment through onActivityResult. And it's all done.

The problem is:

Activity could send the result to only the Fragment that has been attached directly to Activity but not the nested one. That's the reason why onActivityResult of nested fragment would never been called no matter what.

Solution:

1) Start Camera Intent in your Fragment by below code:

       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) Now in your Parent Activity override **onActivityResult() :**

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

You have to call this in parent activity to make it work.

3) In your fragment call:

@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) Reference methods for getting URI:

-> Method for getting Uri from the 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);     } 

-> Method for getting File path from the 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();             }         }     } 

That's it. With this solution, it could be applied for any single fragment whether it is nested or not. And yes, it also covers all the case! Moreover, the codes are also nice and clean.

like image 24
KishuDroid Avatar answered Sep 21 '22 10:09

KishuDroid