Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android camera: onActivityResult() intent is null if it had extras

After searching a lot in all the related issues at Stack Overflow and finding nothing, please try to help me.

I created an intent for capture a picture. Then I saw different behavior at onActivityResult(): if I don't put any extra in the Intent (for small pics) the Intent in onActivityResult is ok, but when I put extras in the intent for writing the pic to a file, the intent in onActivityResult is null!

The Intent creation:

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // without the following line the intent is ok takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); startActivityForResult(takePictureIntent, actionCode); 

Why is it null, and how can I solve it?

like image 729
dvrm Avatar asked Sep 24 '12 11:09

dvrm


People also ask

How does onActivityResult work on Android?

class); startActivityForResult(i, 100); 2.In your secondActivity class write following code for onClick Event For ex: In secondActivity if you want to send back data: Intent intent= new Intent(); intent. putExtra("result",result); setResult(RESULT_OK,intent); finish();

What is onActivityResult?

onActivityResult is the callback you have on the first activity to grab the contacts you choose. Follow this answer to receive notifications.

What is Requestcode in startActivityForResult?

The request code is any int value. The request code identifies the return result when the result arrives. ( You can call startActivityForResult more than once before you get any results.


2 Answers

It happens the same to me, if you are providing MediaStore.EXTRA_OUTPUT, then the intent is null, but you will have the photo in the file you provided (Uri.fromFile(f)).

If you don't specify MediaStore.EXTRA_OUTPUT then you will have an intent which contains the uri from the file where the camera has saved the photo.

Don't know if it as a bug, but it works that way.

EDIT: So in onActivityResult() you no longer need to check for data if null. The following worked with me:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {     switch (requestCode) {         case PICK_IMAGE_REQUEST://actionCode             if (resultCode == RESULT_OK && data != null && data.getData() != null) {                 //For Image Gallery             }             return;          case CAPTURE_IMAGE_REQUEST://actionCode             if (resultCode == RESULT_OK) {                 //For CAMERA                 //You can use image PATH that you already created its file by the intent that launched the CAMERA (MediaStore.EXTRA_OUTPUT)                 return;             }     } } 

Hope it helps

like image 129
richardtz Avatar answered Sep 23 '22 04:09

richardtz


A sample written in Kotlin. You create a Uri for camera app, CameraFragment holds it until camera returns from saving your picture and gives it back to you in onActivityResult as you would expect.

CameraFragment.kt

Acts as an intermediary between consumer and camera app. Takes Uri as input and returns it in data Intent.

class CameraFragment : Fragment() {      companion object {         val TAG = CameraFragment::class.java.simpleName          private val KEY_URI = ".URI"          fun newInstance(uri: Uri, targetFragment: Fragment, requestCode: Int): CameraFragment {             val args = Bundle()             args.putParcelable(KEY_URI, uri)             val fragment = CameraFragment()             fragment.arguments = args             fragment.setTargetFragment(targetFragment, requestCode)             return fragment         }     }      private lateinit var uri: Uri      private var fired = false      override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         retainInstance = true          fired = savedInstanceState?.getBoolean("fired") ?: false          if (!fired) {             val args = arguments             uri = args.getParcelable(KEY_URI)              val i = Intent(MediaStore.ACTION_IMAGE_CAPTURE)             i.putExtra(MediaStore.EXTRA_OUTPUT, uri)             i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)             context.grantUriPermission(i, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)              startActivityForResult(i, targetRequestCode)             fired = true         }     }      override fun onSaveInstanceState(outState: Bundle) {         super.onSaveInstanceState(outState)         outState.putBoolean("fired", fired)     }      override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {         super.onActivityResult(requestCode, resultCode, data)          if (requestCode == targetRequestCode) {             context.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)              val newData = Intent()             newData.data = uri             targetFragment.onActivityResult(requestCode, resultCode, newData)              dismiss()         }     }      private fun dismiss() {         fragmentManager.beginTransaction().remove(this).commit()     } }  /** Grant Uri permissions for all camera apps. */ fun Context.grantUriPermission(intent: Intent, uri: Uri, modeFlags: Int) {     val resolvedIntentActivities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);     for (resolvedIntentInfo in resolvedIntentActivities) {         val packageName = resolvedIntentInfo.activityInfo.packageName;         grantUriPermission(packageName, uri, modeFlags);     } } 

Invoke camera intent

this is a fragment in your app which will trigger the camera. RC_CAMERA is your request code for this action.

val uri = /* Your output Uri. */ val f = CameraFragment.newInstance(uri, this, RC_CAMERA) fragmentManager.beginTransaction().add(f, CameraFragment.TAG).commit() 

Handle camera result

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {     super.onActivityResult(requestCode, resultCode, data)      when(requestCode) {         RC_CAMERA -> {             if (resultCode == Activity.RESULT_OK) {                 val uri = data?.data                 // Do whatever you need.             }         }     } } 
like image 41
Eugen Pechanec Avatar answered Sep 20 '22 04:09

Eugen Pechanec