onActivityResult 从相机返回,Intent null

Posted

技术标签:

【中文标题】onActivityResult 从相机返回,Intent null【英文标题】:onActivityResult returned from a camera, Intent null 【发布时间】:2013-01-11 13:37:12 【问题描述】:

我按照android dev site上相机的说明进行操作

我只是启动相机 Intent,而不是构建自己的相机。

拍照后返回结果的处理示例代码如下。

 protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) 
        if (resultCode == RESULT_OK) 
            // Image captured and saved to fileUri specified in the Intent
            Toast.makeText(this, "Image saved to:\n" +
                    data.getData(), Toast.LENGTH_LONG).show();
         else if (resultCode == RESULT_CANCELED) 
            // User cancelled the image capture
         else 
            // Image capture failed, advise user
        
    

    if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) 
        if (resultCode == RESULT_OK) 
            // Video captured and saved to fileUri specified in the Intent
            Toast.makeText(this, "Video saved to:\n" +
                    data.getData(), Toast.LENGTH_LONG).show();
         else if (resultCode == RESULT_CANCELED) 
            // User cancelled the video capture
         else 
            // Video capture failed, advise user
        
    

resultCode 可以,但data 始终为 NULL,这会导致 NPE。我查看了sdcard,照片真的保存在那里。任何提示?太棒了。

更新:根据要求更新日志信息:

   01-28 19:39:00.547: ERROR/AndroidRuntime(24315): FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to resume activity com.example.CameraTest/com.example.CameraTest.MyCamera: java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=100, result=-1, data=null to activity com.example.CameraTest/com.example.CameraTest.MyCamera: java.lang.NullPointerException
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2455)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2483)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1997)
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3362)
    at android.app.ActivityThread.access$700(ActivityThread.java:127)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1162)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4511)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=100, result=-1, data=null to activity com.example.CameraTest/com.example.CameraTest.MyCamera: java.lang.NullPointerException
    at android.app.ActivityThread.deliverResults(ActivityThread.java:2991)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2442)
    ... 13 more
    Caused by: java.lang.NullPointerException
    at com.example.CameraTest.MyCamera.onActivityResult(MyCamera.java:71)
    at android.app.Activity.dispatchActivityResult(Activity.java:4654)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:2987)
    ... 14 more                                                                                      

【问题讨论】:

发布更多代码和 logcat。 你使用过 MediaStore.EXTRA_OUTPUT 吗? private void fireCameraForImage(int requestCode) Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); startActivityForResult(intent, requestCode); @TungMaiLe 使用fileUri 获取图片路径即可。如果要获取数据路径默认路径,不要放MediaStore.EXTRA_OUTPUT Tks Sieryuu,但为什么 Intent data 为空? 【参考方案1】:

你的代码的问题是这样的:

data.getData()

此调用没有从返回的Intent 中获取带有键“data” 的额外内容。它从返回的Intent 中获取字段data,这可能是null

您需要像这样从返回的Intent 中获取额外的:

data.getExtras().get("data");

其他一些答案已经表明了这一点,嵌入在大量其他代码中。这使得很难真正看到问题所在。

【讨论】:

我有同样的错误,在这种情况下,data 参数为空,所以在你的答案中执行data.getExtras() 仍然会产生 NPE 我也有同样的问题。在某些三星设备中,我的数据参数为空。所以,我不能继续前进。 @JigneshM.Mehta 你看到 KJ50 关于三星手机的回答了吗? @David Wasser:我仍然得到 fileUri.toString() Null 和 KJ50 的答案.. :( @JigneshM.Mehta 请打开一个新问题,发布您的问题、您的代码等,也许有人可以帮助您。这不是寻求帮助的正确地方(在答案的评论中)。【参考方案2】:

Here is the answer from a similar question。好像是三星手机的问题……

基本上,如果您有 code like this 创建 Intent:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

然后,在onActivityResult 中,data.getData() 替换为fileUri.toString(),它将解决您的问题。

【讨论】:

我有时将 fileUri 设为 null。 fileUri.toString() 也不适用于三星手机。 :'( 谢谢 > = 永远(真的) 顺便说一句,将 Nexus-7 平板电脑(和 Cyanogenmod 操作系统)添加到三星手机。【参考方案3】:

使用@KJ50 的解决方案,并使用savedInstanceState 确保不会得到空值。

/**
     * Here we store the file url as it will be null after returning from camera
     * app
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) 
        super.onSaveInstanceState(outState);

        // save file url in bundle as it will be null on screen orientation
        // changes
        outState.putParcelable("file_uri", fileUri);
    

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) 
        super.onRestoreInstanceState(savedInstanceState);

        // get the file url
        fileUri = savedInstanceState.getParcelable("file_uri");
    

【讨论】:

【参考方案4】:

试试下面的代码:

 Button m_btnCamera;
  ImageView m_ivCaptureImage;
  String m_curentDateandTime;
  String m_imagePath;
  Bitmap m_bitmap;

   //Start camera to caputre image.
 Intent m_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  m_intent.putExtra(MediaStore.EXTRA_OUTPUT, getImageUri());
  startActivityForResult(m_intent, TAKE_PHOTO_CODE);

 private Uri getImageUri() throws CustomException
    
    Uri m_imgUri = null;
    File m_file;
    try
    
        SimpleDateFormat m_sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
        m_curentDateandTime = m_sdf.format(new Date());
        m_imagePath = File.getPath() + File.separator + m_curentDateandTime + ".jpg";
        m_file = new File(m_imagePath);
        m_imgUri = Uri.fromFile(m_file);
    
    catch (Exception p_e)
          
    return m_imgUri;        


 @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data)
  
  super.onActivityResult(requestCode, resultCode, data);
 if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK)
    
        m_bitmap = ImageHelper.scaleImage(m_imagePath, 200, 200);
            m_bitmap = ImageHelper.rotateImage(m_bitmap, true, m_rotate);
            m_ivCaptureImage.setImageBitmap(m_bitmap);
    
  

【讨论】:

catch (Exception p_e)我的眼睛在流血。 捕获各种异常然后忽略它们(不记录或任何东西)肯定会提高代码的健壮性:-(【参考方案5】:

试试这个

public void onActivityResult(int requestCode, int resultCode, Intent data) 

    switch (requestCode) 
        case PICK_IMAGE_ID:

            Bitmap bitmap = ImagePicker.getImageFromResult(this.getActivity(), resultCode, data);

            if(data!=null)
                //set image view
            
            break;
        default:
            super.onActivityResult(requestCode, resultCode, data);
            break;
    

【讨论】:

【参考方案6】:

此代码将帮助您

getData()方法只在Android版本高于M时返回数据,否则返回null结果。

if (resultCode == Activity.RESULT_OK) 

                //Check Android version, as intent.getData() will return data only if v is above or equal to M otherwise the data will be null
                if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) 
                    Uri selectedImageURI = imageReturnedIntent.getData();
                    Toast.makeText(getActivity(), "URI Path:" + selectedImageURI, Toast.LENGTH_LONG).show();
                 else 
                    Bitmap photo = (Bitmap) imageReturnedIntent.getExtras().get("data");
                    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                    photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
                    String path = MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), photo, "Title", null);
                    Uri selectedImageURI = Uri.parse(path);
                    Toast.makeText(getActivity(), "URI Path:" + selectedImageURI, Toast.LENGTH_LONG).show();
                
            

【讨论】:

【参考方案7】:

试试下面的代码.....

btn_capture.setOnClickListener(new OnClickListener() 

        public void onClick(View v) 

            Intent cameraIntent = new  Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
            startActivityForResult(cameraIntent, CAMERA_REQUEST); 
        
    );
 protected void onActivityResult(int requestCode, int resultCode, Intent data)


             if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK)   
                 Bitmap photo = (Bitmap) data.getExtras().get("data"); 
                 img.setImageBitmap(photo);
              
          

    

最后你将下面的代码添加到你的清单中

   <uses-feature android:name="android.hardware.camera"></uses-feature> 

【讨论】:

以上是关于onActivityResult 从相机返回,Intent null的主要内容,如果未能解决你的问题,请参考以下文章

onActivityResult 图像 uri 不起作用

片段中未调用 onActivityResult

从相机返回结果时也会调用 onCreate 方法

在棒棒糖中通过相机拍摄照片后,在 onActivityResult() 方法中获取空意图

启动相机意图时未调用 onActivityResult?

相机不进入 onActivityResult