web-dev-qa-db-fra.com

Pointeur nul après avoir capturé une image à l'aide d'une caméra Android

dans mon application, j'utilise un appareil photo d'appareils Android pour capturer une image. pour certains appareils, cela fonctionne bien, mais d'autres ne le sont pas. Je viens juste de le tester sur LG nexus 4 E960, après avoir capturé l'image, mon application est tombée en panne sans pouvoir enregistrer le résultat. Voici mon code:

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

dans l'activitéRésultat:

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

une fois capturée et sauvegardée, l’image montrée dans l’activité suivante intitulée Crop.class est ici mon 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

J'ai un problème pour ouvrir/utiliser la caméra qui fonctionne sur la plupart des appareils Android, l'objectif principal de ce projet est fortement dépendant de l'utilisation de la caméra. donnez-moi s'il vous plaît votre aide, merci ..

12
bohr

essayez ci-dessous le code,

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

où getOutputMediaFile (int) sera,

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

et enfin,

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

À votre santé....:)

12
Melbourne Lopes

Pour ceux qui ne pourraient pas résoudre ce problème avec aucune des réponses ici, voici le chemin. 

Vous avez un membre picUri dans lequel vous enregistrez l'URI du fichier image temporaire avant que la startActivityForResult ne soit appelée pour le lancement de l'application Appareil photo.

Lorsque l'application s'interrompt, ces informations risquent de se perdre (comme dans mon cas) et vous les trouverez sous la forme null lorsque vous revenez en activité pour l'utiliser pour obtenir l'image enregistrée de l'appareil photo. 

Ensuite, vous aurez NullPointerException.

La bonne façon de garder picUri est de le sauvegarder onSaveInstanceState(Bundle) et de le restaurer onRestoreInstanceState(Bundle) pour éviter la perte d'informations.

Voici comment faire:

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

}

M'a donné mal à la tête pendant deux heures.

8
Buddy

Essaye celui-là 

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

remplacer 

picUri = getIntent().getData();

avec

picUri = data.getData();

et essayez une fois ...

0
Gopal Gopi

Vous devez dire à la caméra pour enregistrer le chemin de l'image comme ci-dessous:

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
Riser

J'ai le même problème dans mon application. Le problème est que, lorsque onActivityResult est exécuté, les données sont nulles et vous ne pouvez rien obtenir de l'activité de la caméra. Il devrait y avoir un autre moyen de résoudre ceci plutôt que d'utiliser la classe Application, car cela devient vraiment compliqué lorsque vous manipulez plus d'une photo.

0
AZorrozua

Vous voyez, j'ai encore fait une chose, cela vous fera économiser du temps. Le fait est que l’objet de données dans onActivityResult () est le contenu principal à examiner. L'objet de données est en train de devenir nul lorsqu'il s'agit d'utiliser le code p = pour le prochain déplacement. Vous allez simplement mettre la condition if-else sur celle-ci et exécuter votre projet. 

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

Regardez ça, c'est facile et vous ferez votre travail immédiatement.

0
Alok

sur certains appareils, onActivityResult est appelé pas de reprise d'activité. Au lieu de cela, l'activité est redémarrée après le rappel de l'objectif de la caméra, de sorte que picurl puisse redevenir nul. Nous pouvons utiliser la classe d'application pour conserver la référence de la variable. 

Nous pouvons créer notre propre classe d'application 

1.Dans le manifeste Android, nous devons spécifier la classe d'application nous allons utiliser

  <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.Créez la classe d'application

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

3.Inside the Activity utilisation

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