【问题标题】:Null pointer after capturing image using android camera使用android相机捕获图像后的空指针
【发布时间】:2013-12-30 10:58:03
【问题描述】:

在我的应用程序中,我使用 android 设备的相机来捕捉图像。对于某些设备,它可以正常工作,但有些则不行。我刚刚在 LG nexus 4 E960 上对其进行了测试,在我捕获图像后,我的应用程序崩溃了,无法保存结果。 这是我的代码:

//Using intent to open camera
  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  startActivityForResult(intent,CAMERA_CAPTURE); 

在活动结果中:

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if(resultCode==RESULT_OK)
    {
        if(requestCode==CAMERA_CAPTURE)
        {   
            Bitmap pictTaken = null ;
            Bundle extras = data.getExtras();
            if(extras.keySet().contains("data"))
            {
                pictTaken = (Bitmap) extras.get("data");
                picUri = getIntent().getData();
            }
                    else{
                     picUri = getIntent().getData();
                try {
                    pictTaken = decodeUri(picUri);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                     }
            Intent cropIntent= new Intent (this, Crop.class);
            cropIntent.putExtra("data", picUri.toString());
            cropIntent.putExtra("pict", pictTaken);
            cropIntent.putExtra("code","camera");
            startActivity(cropIntent);
            }
        }

捕获并保存后,图像显示在名为 Crop.class 的下一个活动中 这是我的日志

     12-12 13:26:36.340: E/AndroidRuntime(23575): FATAL EXCEPTION: main
 12-12 13:26:36.340: E/AndroidRuntime(23575): Process: com.example.cobaandroid, PID: 23575
 12-12 13:26:36.340: E/AndroidRuntime(23575): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.cobaandroid/com.example.cobaandroid.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.app.ActivityThread.deliverResults(ActivityThread.java:3368)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.app.ActivityThread.handleSendResult(ActivityThread.java:3411)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.app.ActivityThread.access$1300(ActivityThread.java:138)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.os.Handler.dispatchMessage(Handler.java:102)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.os.Looper.loop(Looper.java:136)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.app.ActivityThread.main(ActivityThread.java:5050)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at java.lang.reflect.Method.invoke(Native Method)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
 12-12 13:26:36.340: E/AndroidRuntime(23575): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at com.example.cobaandroid.MainActivity.onActivityResult(MainActivity.java:226)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.app.Activity.dispatchActivityResult(Activity.java:5433)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   at android.app.ActivityThread.deliverResults(ActivityThread.java:3364)
 12-12 13:26:36.340: E/AndroidRuntime(23575):   ... 9 more

我在打开/使用适用于大多数安卓设备的相机时遇到了问题,这个项目的主要目标很大程度上取决于相机的使用。请给我你的帮助,谢谢..

【问题讨论】:

  • 检查你的java类的第226行。
  • 感谢您的回复,我的第 226 行代码有什么问题?
  • 我在第 226 行的代码:cropIntent.putExtra("data",picUri.toString())
  • 我是你将 picUri 的值设为 null。
  • 查看提供的答案。

标签: android nullpointerexception image-capture


【解决方案1】:

试试下面的代码,

        Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

        File file=getOutputMediaFile(1);
        picUri = Uri.fromFile(file); // create
        i.putExtra(MediaStore.EXTRA_OUTPUT,picUri); // set the image file

        startActivityForResult(i, CAPTURE_IMAGE);

getOutputMediaFile(int) 将在哪里,

/** Create a File for saving an image */
private  File getOutputMediaFile(int type){
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyApplication");

    /**Create the storage directory if it does not exist*/
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            return null;
        }
    }

    /**Create a media file name*/
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == 1){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".png");
    } else {
        return null;
    }

    return mediaFile;
}

最后,

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK) {
        Intent i;
        switch (requestCode) {
        case CAPTURE_IMAGE:
            //THIS IS YOUR Uri
            Uri uri=picUri; 
            break;
        }
    }   
}

干杯....:)

【讨论】:

  • “CAPTURE_IMAGE”从何而来?
  • 只是请求代码.....在顶部定义它,如 private static final int CAPTURE_IMAGE = 0;
【解决方案2】:

对于那些无法通过此处的任何答案解决此问题的人,这就是方法。

您有一个成员 picUri,在调用 startActivityForResult 启动相机应用程序之前,您在其中保存临时图像文件 URI。

当应用程序暂停时,此信息可能会丢失(如我的情况),当您返回活动以使用它从相机获取保存的图像时,您会发现它为null

然后,你会得到NullPointerException

保留picUri的正确方法是保存onSaveInstanceState(Bundle)并恢复onRestoreInstanceState(Bundle)以防止信息丢失。

这是怎么做的:

// Save the activity state when it's going to stop.
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    outState.putParcelable("picUri", picUri);
}

// Recover the saved state when the activity is recreated.
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    picUri= savedInstanceState.getParcelable("picUri");

}

让我头疼了两个小时。

【讨论】:

  • 这很好,这正是我的问题
【解决方案3】:

替换

picUri = getIntent().getData();

picUri = data.getData();

然后尝试一次...

【讨论】:

  • 谢谢,这适用于我的三星,但不适用于 LG。在保存之前拍摄图像后应用程序崩溃
【解决方案4】:

您必须告诉相机保存图像路径,如下所示:

Uri picUri;

   Intent intentAmbil = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
   String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() +          "/picture.jpg";  
   File imageFile = new File(imageFilePath); 
   picUri = Uri.fromFile(imageFile); // convert path to Uri        
   intentAmbil.putExtra( MediaStore.EXTRA_OUTPUT,  picUri );
   startActivityForResult(intentAmbil, REQUEST_MAKE_PHOTO);


@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    switch (requestCode) {
        case REQUEST_MAKE_PHOTO:
            if (resultCode == Activity.RESULT_OK) {
                // do something with mMakePhotoUri
            }
            return;
        default: // do nothing
            super.onActivityResult(requestCode, resultCode, data);
    }
}

【讨论】:

  • 注意:在三星设备中,onActivityResult 不是在活动恢复时调用,而是在从相机意图回调后重新启动活动,因此 picurl 可以为 null再次 - 我们可以使用 应用程序类 来保持变量的引用
  • @AromalSasidharan 我不明白 :( 我如何使用应用程序类?
  • @segi 仍然无法正常工作,我得到 java.lang.NullPointerException
【解决方案5】:

试试这个

if (resultCode != RESULT_CANCELED) {
            if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {

                if (requestCode == CAMERA_REQUEST) {
                    if (data != null) {
                        Bitmap photo = (Bitmap) data.getExtras().get("data");
                        imageView.setImageBitmap(photo);
                    }
                }
            }            
            Drawable drawable = imageView.getDrawable();
            if (drawable instanceof BitmapDrawable) {
                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
                bitmap1 = bitmapDrawable.getBitmap();
            }
        }
    }

    if (bitmap1 != null) {          
        bitmap1 = Bitmap.createScaledBitmap(bitmap1, 512, 512, false);
        imageView.setImageBitmap(bitmap1);
        @SuppressWarnings("unused")
        String path = SaveImage_Sta(bitmap1, "stat");
    } else {
        Log.i("bitmap............", "bitmap1 is null");
    }

【讨论】:

    【解决方案6】:

    在某些设备中,onActivityResult 不是在活动恢复时调用,而是在从相机意图回调后重新启动活动,因此 picurl 可以再次为空 - 我们可以使用应用程序类来保持对变量的引用

    我们可以创建自己的应用类

    1.在android manifest中我们必须指定我们将要使用的应用程序类

      <application android:name=".MyApplication" 
      >
     <activity
            ........         
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
          </activity> 
          <activity> 
              ....
          </activity>
            ....
      </application>
    

    2.创建应用类

    public class MyApplication extends Application {
       private Uri picUri;
       public void getPicUri()
       {
         return picUri;
       } 
       public void setPictUri(Uri auri)
       {
         picUri = aUri;
       } 
    }
    

    3.Activity内部使用

      //call the camera intent and pass the created a tempfile uri and use the tempfile uri
      MyApplication myApplication = (MyApplication)getApplication();
      myApplication.setPictUri(aUri);
      ....
     ....
     public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    switch (requestCode) {
        case REQUEST_MAKE_PHOTO:
            if (resultCode == Activity.RESULT_OK) {
                // do something with mMakePhotoUri
                MyApplication myApplication = (MyApplication)getApplication();
                myApplication.getPicUri();// use the pic uri
            }
            return;
        default: // do nothing
            super.onActivityResult(requestCode, resultCode, data);
       }  
    
     }
    

    【讨论】:

    • 它应该是public Uri getPicUri(),因为您不能返回空白。其次,我应该在哪里准确调用 setPicUri(aUri) ?一旦我用Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intentPicture,PICK_FROM_CAMERA_EDIT); 调用相机意图,下次我可以控制任何东西都在 onActivityResult 块中
    【解决方案7】:

    我在我的应用程序中遇到了同样的问题。 问题是执行 onActivityResult 时,数据为空,因此您无法从相机 Activity 中获取任何内容。 应该有另一种方法来解决这个问题,而不是使用 Application 类,因为当您处理多张照片时它会变得非常复杂。

    【讨论】:

      【解决方案8】:

      请看,我还做了一件事,可能会节省您的时间。问题是 onActivityResult() 中的数据对象是要查看的主要内容。在为下一步操作 p=code 时,数据对象为空。你要做的就是在上面加上 if-else 条件并运行你的项目。

      protected void onActivityResult(int requestCode, int resultCode, Intent data)
      {
      if(data !=null){
        if(resultCode==RESULT_OK)
          {
              if(requestCode==CAMERA_CAPTURE)
              {   
                  Bitmap pictTaken = null ;
                  Bundle extras = data.getExtras();
                  if(extras.keySet().contains("data"))
                  {
                      pictTaken = (Bitmap) extras.get("data");
                      picUri = getIntent().getData();
                  }
                          else{
                           picUri = getIntent().getData();
                      try {
                          pictTaken = decodeUri(picUri);
                      } catch (FileNotFoundException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }
                           }
                  Intent cropIntent= new Intent (this, Crop.class);
                  cropIntent.putExtra("data", picUri.toString());
                  cropIntent.putExtra("pict", pictTaken);
                  cropIntent.putExtra("code","camera");
                  startActivity(cropIntent);
                  }
              }
      }else{
         //on cancel event or something else you want to do
      }
      }
      

      看看这个,它很简单,并且会立即完成您的工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多