android 相机:onActivityResult() 意图是 null 如果它有额外的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12564112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android camera: onActivityResult() intent is null if it had extras
提问by dvrm
After searching a lot in all the related issues at Stack Overflow and finding nothing, please try to help me.
在 Stack Overflow 的所有相关问题中搜索了很多但一无所获后,请尝试帮助我。
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
!
我创建了一个用于捕获图片的意图。然后我看到了不同的行为onActivityResult()
:如果我没有在 Intent 中添加任何额外内容(对于小图片),则 onActivityResult 中的 Intent 是可以的,但是当我将额外内容放入将图片写入文件的意图中时,onActivityResult 中的意图是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?
为什么它为空,我该如何解决?
回答by richardtz
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)
).
它发生在我身上,如果您提供MediaStore.EXTRA_OUTPUT
,则意图为空,但是您将在您提供的文件中拥有照片 ( 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.
如果您没有指定,MediaStore.EXTRA_OUTPUT
那么您将拥有一个包含来自相机保存照片的文件中的 uri 的意图。
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:
编辑:因此在 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;
}
}
}
Hope it helps
希望能帮助到你
回答by Eugen Pechanec
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.
用 Kotlin 编写的示例。您创建了一个Uri
相机应用程序,CameraFragment
保持它直到相机从保存您的照片中返回并onActivityResult
按照您的预期将其返回给您。
CameraFragment.kt
相机片段.kt
Acts as an intermediary between consumer and camera app. Takes Uri
as input and returns it in data Intent
.
充当消费者和相机应用程序之间的中介。注意到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);
}
}
Invoke camera intent
调用相机意图
this
is a fragment in your app which will trigger the camera. RC_CAMERA
is your request code for this action.
this
是您的应用程序中将触发相机的片段。RC_CAMERA
是您对此操作的请求代码。
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.
}
}
}
}
回答by Pradeep Kumar
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.
当我们将捕捉从相机图像中的机器人则Uri
或data.getdata()
来自空。我们有两种解决方案来解决这个问题。
- We can got the Uri path from the Bitmap Image
- We can got the Uri path from cursor.
- 我们可以从 Bitmap Image 中得到 Uri 路径
- 我们可以从游标中获取 Uri 路径。
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 :
首先,我将告诉如何从位图图像获取 Uri:完整代码是:
First we will capture image through Intent that will same for both methods so this code i will write one time only here :
首先,我们将通过 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);
}
}
});
Now we will Implement OnActivityResult :-(This will be same for both above 2 methods):-
现在我们将实现 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();
}
}
\now we will create all above method to create Uri from Image and Cursor methods via classes:
\现在我们将创建上述所有方法,以通过类从 Image 和 Cursor 方法创建 Uri:
Now URI path from Bitmap Image
现在来自位图图像的 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
\来自保存图像的真实路径的Uri
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);
}
回答by Mun0n
Where did you create the f
for the Uri.fromFile(f)
?
你在哪里创建f
的Uri.fromFile(f)
?
It must be a valid File
object. Try to create it before the EXTRA_OUTPUT
line.
它必须是一个有效的File
对象。尝试EXTRA_OUTPUT
在行之前创建它。
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);
回答by Jaden Gu
use the following:
使用以下内容:
Bitmap bitmap = data.getExtras().getParcelable("data");
位图 bitmap = data.getExtras().getParcelable("data");
it works.
有用。