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

大城市里の小女人 提交于 2019-12-17 10:43:21

问题


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?


回答1:


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




回答2:


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.
            }
        }
    }
}



回答3:


Where did you create the ffor the Uri.fromFile(f)?

It must be a valid File object. Try to create it before the EXTRA_OUTPUT line.

File f = new File("valid path");

Try with something like this:

File file = new File(dataFile);
Uri outFileUri = Uri.fromFile(file);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, outFileUri);
startActivityForResult(intent, TAKE_PHOTO);



回答4:


When we will capture the image from Camera in android then Uri or data.getdata() comes null. we have two solutions to resolve this issue.

  1. We can got the Uri path from the Bitmap Image
  2. We can got the Uri path from cursor.

I will implement all methods here, Please carefully watch and read these:-

First i will tell how to get Uri from Bitmap Image: Complete code is :

First we will capture image through Intent that will same for both methods so this code i will write one time only here :

 // Capture Image


  captureImg.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (intent.resolveActivity(getPackageManager()) != null) {
                startActivityForResult(intent, reqcode);
            }

        }
    });

Now we will Implement OnActivityResult :-(This will be same for both above 2 methods):-

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


            if(requestCode==reqcode && resultCode==RESULT_OK)
            {

    Bitmap photo = (Bitmap) data.getExtras().get("data");
    ImageView.setImageBitmap(photo);

                // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
                Uri tempUri = getImageUri(getApplicationContext(), photo);

                \\ Show Uri path based on Image
                Toast.makeText(LiveImage.this,"Here "+ tempUri, Toast.LENGTH_LONG).show();

               \\ Show Uri path based on Cursor Content Resolver
                Toast.makeText(this, "Real path for URI : "+getRealPathFromURI(tempUri), Toast.LENGTH_SHORT).show();
    }
            else
            {
                Toast.makeText(this, "Failed To Capture Image", Toast.LENGTH_SHORT).show();
            }
        }

\now we will create all above method to create Uri from Image and Cursor methods via classes:

Now URI path from Bitmap Image

 private Uri getImageUri(Context applicationContext, Bitmap photo) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(LiveImage.this.getContentResolver(), photo, "Title", null);
        return Uri.parse(path);
    }

\ Uri from Real path of saved image

  public String getRealPathFromURI(Uri uri) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        return cursor.getString(idx);
    }



回答5:


use the following:

Bitmap bitmap = data.getExtras().getParcelable("data");

it works.



来源:https://stackoverflow.com/questions/12564112/android-camera-onactivityresult-intent-is-null-if-it-had-extras

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!