Нулевой указатель после захвата изображения с помощью камеры Android

в моем приложении я использую камеру 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, вот мой 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, основная цель этого проекта сильно зависит от использования камеры. пожалуйста, передайте мне вашу помощь, спасибо ..


person bohr    schedule 12.12.2013    source источник
comment
Проверьте строку 226 вашего класса Java.   -  person Siddharth_Vyas    schedule 12.12.2013
comment
спасибо за ответ, что не так с моим кодом в строке 226?   -  person bohr    schedule 12.12.2013
comment
мой код в строке 226: cropIntent.putExtra(data,picUri.toString())   -  person bohr    schedule 12.12.2013
comment
Может быть, вы получаете значение picUri как нулевое.   -  person Siddharth_Vyas    schedule 12.12.2013
comment
Ознакомьтесь с предоставленными ответами.   -  person Siddharth_Vyas    schedule 12.12.2013
comment
все еще складывается и вылетает :(   -  person bohr    schedule 12.12.2013


Ответы (8)


попробуйте код ниже,

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

Ваше здоровье....:)

person Melbourne Lopes    schedule 18.03.2014
comment
Откуда взялось CAPTURE_IMAGE? - person Leonard Febrianto; 25.10.2016
comment
Это просто код запроса... определите его вверху, как private static final int CAPTURE_IMAGE = 0; - person Melbourne Lopes; 26.10.2016

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

У вас есть участник 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");

}

У меня два часа болела голова.

person Buddy    schedule 20.08.2015
comment
это здорово, это была именно моя проблема - person JRowan; 12.06.2019

заменять

picUri = getIntent().getData();

с

picUri = data.getData();

и попробуй один раз...

person Gopal Gopi    schedule 12.12.2013
comment
спасибо, это сработало для моего samsung, но не для LG one. сбой приложения сразу после съемки изображения перед его сохранением - person bohr; 12.12.2013

Вы должны указать камере сохранить путь к изображению, как показано ниже:

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);
    }
}
person Sagar Maiyad    schedule 12.12.2013
comment
примечание: в устройствах Samsung onActivityResult вызывается не при возобновлении активности, вместо этого активность перезапускается после обратного вызова из намерения камеры, поэтому picurl может снова быть нулевым — мы можем использовать класс приложения, чтобы сохранить ссылку на переменную - person Aromal Sasidharan; 12.12.2013
comment
@AromalSasidharan я не понял :( как я использую класс приложения? - person bohr; 12.12.2013
comment
@segi все еще не работает, я получаю java.lang.NullPointerException - person bohr; 12.12.2013

Попробуй это

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");
    }
person NagarjunaReddy    schedule 12.12.2013

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

Мы можем создать собственный класс приложения

1. в манифесте 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. Внутри использования 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);
   }  

 }
person Aromal Sasidharan    schedule 12.12.2013
comment
Это должно быть public Uri getPicUri(), так как вы не можете вернуться с пустотой. Во-вторых, где именно я должен вызывать setPicUri(aUri)? Как только я вызову намерение камеры с помощью Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intentPicture,PICK_FROM_CAMERA_EDIT);, в следующий раз, когда я смогу что-то контролировать, это будет в блоке onActivityResult. - person erdomester; 07.03.2015

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

person azorrozua    schedule 09.12.2014

Смотрите, я сделал еще одну вещь, может быть, это сэкономит ваше время. Дело в том, что объект данных в 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
}
}

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

person Alok    schedule 24.02.2017