2013-12-12 3 views
11

в моем приложении, я использую камеру устройств Android для захвата изображения. для некоторых устройств он работает нормально, а некоторые нет. Я только что протестировал его на LG nexus 4 E960, после того как я снял изображение, мое приложение попало в катастрофу, не сохранив результат. это мой код:Null указатель после захвата изображения с помощью камеры андроида

//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

Проверьте строку 226 вашего класса java. –

+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 (целое) будет,

/** 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

Это просто код запроса ..... определить его сверху, как private static final int CAPTURE_IMAGE = 0; –

0

заменить

picUri = getIntent().getData(); 

с

picUri = data.getData(); 

и один раз попробовать ...

+0

спасибо, это сработало для моего samsung, но не для 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

примечание: в устройствах samsung ** onActivityResult ** называется не активным резюме вместо этого активность перезапускается после обратного вызова с камеры, поэтому * picurl * может быть снова пустым - мы можем использовать класс приложения ** **, чтобы сохранить ссылку на переменную –

+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 андроида манифеста мы должны определить класс приложения мы будем использовать

<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.Create Заявление класса

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()', поскольку вы не можете вернуться с пустотой. Во-вторых, где следует ли я назвать setPicUri (aUri) точно? Как только я вызываю камеру с помощью «Intent intentPicture = new Intent (MediaStore.ACTION_IMAGE_CAPTURE); \t \t \t \t startActivityForResult (intentPicture, PICK_FROM_CAMERA_EDIT) 'в следующий раз я могу контролировать что-либо в блоке onActivityResult – erdomester

0

У меня есть один и тот же вопрос в моем приложении. Проблема заключается в том, что при выполнении onActivityResult данные равны нулю, поэтому вы не можете получить что-либо из камеры. Должен быть другой способ решить это, а не использовать класс Application, потому что он становится очень сложным, когда вы обрабатываете несколько фотографий.

8

Для тех, кто не смог решить эту проблему с помощью любого из ответов здесь, вот путь.

У вас есть участник picUri, в котором вы сохраняете URI временного файла изображения до того, как для запуска приложения «Камера» вызывается startActivityForResult.

Когда приложение приостанавливается, эта информация может потеряться (как в моем случае), и вы вернетесь к ней как 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() является основное содержание, на которое нужно обратить внимание. Объект данных имеет значение null, когда дело касается 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 
} 
} 

Проверьте это, это легко и сделает вашу работу в пути.

Смежные вопросы