web-dev-qa-db-ja.com

Androidカメラを使用して画像をキャプチャした後のヌルポインタ

私のアプリケーションでは、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デバイス、このプロジェクトの主な目標はカメラの使用に大きく依存します。助けてください、ありがとうございます..

12
bohr

以下のコードを試してください、

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

乾杯....:)

13
Melbourne Lopes

ここでの答えのいずれかでこの問題を解決できなかった人のために、ここに方法があります。

カメラアプリを起動するために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");

}

2時間頭痛がした。

9
Buddy

これを試してください

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
NagarjunaReddy

交換

picUri = getIntent().getData();

picUri = data.getData();

一度試してみてください...

0
Gopal Gopi

以下のように画像パスを保存するようにカメラに指示する必要があります。

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);
    }
}
0
Sagar Maiyad

アプリでも同じ問題が発生します。問題は、onActivityResultが実行されると、データがnullになるため、カメラのアクティビティから何も取得できないことです。複数の写真を処理すると非常に複雑になるため、Applicationクラスを使用するのではなく、これを解決する別の方法が必要です。

0
AZorrozua

もう1つやったことがあるので、時間を節約できるかもしれません。重要なのは、onActivityResult()のデータオブジェクトが主なコンテンツであるということです。次の移動のためにp = codeを操作する場合、データオブジェクトはnullです。あなたがすることは、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
}
}

これをチェックしてください、それは簡単で、外出先であなたの仕事をします。

0
Alok

一部のデバイスでは、onActivityResultはアクティビティ再開時に呼び出されず、代わりにカメラインテントからのコールバック後にアクティビティが再開されるため、picurlを再びnullにすることができます-アプリケーションクラスを使用して変数の参照を保持できます

独自のアプリケーションクラスを作成できます

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.アクティビティ内での使用

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