2013-12-12 90 views
11

在我的应用程序中,我使用android设备相机捕捉图像。对于一些设备来说它工作正常,但有些设备却不行我刚刚在LG nexus 4 E960上进行了测试,在拍摄完图像后,我的应用程序崩溃而无法保存结果。 这是我的代码:使用安卓相机拍摄图像后的空指针

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

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 这里是我的logcat

 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 

我得到了一个问题,打开/使用在大多数android设备上工作的相机,这个项目的主要目标很大程度上取决于相机的使用。请交给我你的帮助,感谢你..

+0

检查您的java类的第226行。 –

+0

感谢您的回复,我的代码在226行怎么了? – bohr

+0

什么是226线? – Shashika

回答

11

尝试下面的代码,

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

干杯.... :)

+1

哪里 “CAPTURE_IMAGE” 从何而来? –

+0

这只是请求代码.....定义它在顶部像私人静态最终诠释CAPTURE_IMAGE = 0; –

0

更换

picUri = getIntent().getData(); 

picUri = data.getData(); 

,并尝试一次...

+0

谢谢,这对我的三星而言,但不适用于LG one.the应用程序在拍摄之前拍摄图像后崩溃 – bohr

0

你要告诉相机保存图像路径一样如下:

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); 
    } 
} 
+2

注:在三星设备** onActivityResult **被称为不在活动简历相反,从摄像机意图回调后重新开始活动,所以* picurl *可以再次为空 - 我们可以使用tha **应用程序类**来保持变量的参考 –

+0

感谢您的回复,我如何初始化f? – bohr

+0

@ AromalSasidharan我不明白:(我如何使用应用程序类? – bohr

0

试试这个

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"); 
    } 
0
在某些设备onActivityResult不叫上活动的简历,而不是活动从相机意图回调后重新

,所以picurl可以再次为空 - 我们可以使用应用程序类,以保持的参考可变

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

1.in Android清单,我们必须指定应用程序类我们将使用

<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.Inside活动使用

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

} 
+0

它应该是'public Uri getPicUri()',因为你不能用void返回。我应该完全调用setPicUri(aUri)吗?一旦我用'Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)调用相机意图; \t \t \t \t startActivityForResult(intentPicture,PICK_FROM_CAMERA_EDIT);'下一次我能控制的事情是在onActivityResult块 – erdomester

0

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

8

对于那些无法解决这个问题的人来说,这里就是这样。

您有一个成员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"); 

} 

让我头痛了两个小时。

+0

这样的答案。保持良好的工作 – VVB

0

看我已经做了一件事情,可能会节省你的时间。问题是onActivityResult()中的数据对象是要查看的主要内容。数据对象在为下一步移动操作p =代码时为空。你要做的就是把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 
} 
} 

检查一下,这很容易,并会做你的工作。

相关问题