【问题标题】:android camera: onActivityResult() intent is null if it had extrasandroid 相机:onActivityResult() 意图为空,如果它有额外的
【发布时间】:2012-09-24 11:26:57
【问题描述】:

在堆栈溢出的所有相关问题中搜索了很多后,一无所获,请尝试帮助我。

我创建了一个捕获图片的意图。然后我在onActivityResult() 看到了不同的行为:如果我没有在 Intent 中添加任何额外内容(对于小图片),onActivityResult 中的 Intent 是可以的,但是当我在将图片写入文件的意图中添加额外内容时, onActivityResult 中的意图是 null!

意图创建:

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

为什么它为空,我该如何解决?

【问题讨论】:

  • 在 OnActivityForResult() 内部后,您是否能够弄清楚如何使用 Uri.fromFile(f) 属性?

标签: android android-camera-intent


【解决方案1】:

我也遇到了同样的情况,如果您提供MediaStore.EXTRA_OUTPUT,那么意图为空,但您提供的文件中会包含照片 (Uri.fromFile(f))。

如果您不指定 MediaStore.EXTRA_OUTPUT,那么您的意图将包含相机保存照片的文件中的 uri。

不知道它是否是一个错误,但它是这样工作的。

编辑: 因此,在 onActivityResult() 中,您不再需要检查数据是否为 ​​null。以下对我有用:

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

希望对你有帮助

【讨论】:

  • 感谢您的回复。我怎样才能给相机路径以另一种方式保存照片?
  • 如果你没有指定EXTRA_OUPTUT,你将有一个Intent,其中包含图片的uri,但它将是一个缩略图(不是全分辨率的)。另一种方法,可能是使用 Camera API 并创建一个 Camera 实例,但我没有这方面的经验。
  • 问你一个问题:为什么你需要一个意图?我的意思是,你的文件里有照片,还不够吗?它没有按预期工作,因为意图是空的,但至少你得到了照片。
  • 因为我想用 extras.get("data") 获取 img 以将其显示在屏幕上。这是更简单的方法,不是吗?
  • 获得文件后,您可以通过多种不同的方式显示它,例如,使用 Bitmap.decodeFile 创建一个位图(如果需要,您可以在此处重新缩放),并使用 ImageView 在 ImageView 中设置。设置图像位图。另一种选择是使用 ImageView.setImageUri 并提供文件的 Uri。
【解决方案2】:

用 Kotlin 编写的示例。您为相机应用程序创建了一个UriCameraFragment 保留它,直到相机从保存您的照片返回并在onActivityResult 中将其返回给您,正如您所期望的那样。

CameraFragment.kt

充当消费者和相机应用之间的中介。将Uri 作为输入并在数据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);
    }
}

调用相机意图

this 是您应用中的一个片段,它将触发相机。 RC_CAMERA 是您执行此操作的请求代码。

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

处理相机结果

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

【讨论】:

  • val uri = 应该放什么样的数据?
  • 可能是来自您的FileProviderUri 指向一个私有缓存文件。
【解决方案3】:

您在哪里为Uri.fromFile(f) 创建了f

它必须是一个有效的File 对象。尝试在EXTRA_OUTPUT 行之前创建它。

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

试试这样的:

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

【讨论】:

  • 我之前创建了这个。我确定文件对象是有效的,因为图片保存在那里没问题。
  • TAKE_PHOTO 是 1888 年?这样 onActivityResult() 根本没有被调用(对我来说..)它是为你调用的吗?我很困惑。
  • TAKE_PHOTO 是一个你应该定义的私有变量,传递给捕获动作的方法
【解决方案4】:

当我们将在 android 中从相机捕获图像时,Uridata.getdata() 为空。我们有两种解决方案来解决这个问题。

  1. 我们可以从Bitmap Image中获取Uri路径
  2. 我们可以从光标处获取 Uri 路径。

我将在这里实现所有方法,请仔细阅读:-

首先我将讲述如何从位图图像中获取 Uri: 完整代码为:

首先,我们将通过 Intent 捕获图像,这两种方法都相同,所以这段代码我只在这里写一次:

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

        }
    });

现在我们将实现 OnActivityResult :-(这对于上述两种方法都是相同的):-

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

\现在我们将创建上述所有方法以通过类从 Image 和 Cursor 方法创建 Uri:

现在位图图像的 URI 路径

 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】:

    使用以下内容:

    位图bitmap = data.getExtras().getParcelable("data");

    它有效。

    【讨论】:

    • getExtras() 为 null 当您有 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    相关资源
    最近更新 更多