2013-12-12 22 views
11

w mojej aplikacji, używam aparatu urządzenia z systemem Android, aby uchwycić obraz. dla niektórych urządzeń działa dobrze, ale niektóre nie. Właśnie przetestowałem to na LG nexus 4 E960, po tym jak zrobiłem zdjęcie, które spowodowało awarię mojej aplikacji, bez możliwości zapisania wyniku. to mój kod:Null wskaźnik po przechwytywaniu obrazu za pomocą aparatu Android

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

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

po przechwycone i zapisać go, pokazanie obrazu w kolejnej aktywności nazywa Crop.class tutaj jest mój 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 

Mam problem z otwieraniem/używaniem aparatu, który działa na większości urządzeń z Androidem, główny cel tego projektu jest silnie uzależniony od korzystania z aparatu. proszę podaj mi swoją pomoc, dziękuję ..

+0

Sprawdź linię 226 swojej klasy Java. –

+0

dziękuję za odpowiedź, co jest nie tak z moim kodem w linii 226? – bohr

+0

co jest w linii 226? – Shashika

Odpowiedz

11

try poniżej kod,

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

gdzie getOutputMediaFile (int) będzie,

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

wreszcie

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

Cheers .... :)

+1

Skąd "CAPTURE_IMAGE" pochodzi? –

+0

To tylko kod żądania ..... zdefiniuj go na górze, tak jak w przypadku prywatnego statycznego finału, CAP CAPRERE_IMAGE = 0; –

0

zastąpić

picUri = getIntent().getData(); 

z

picUri = data.getData(); 

i spróbować jeszcze raz ...

+0

dzięki, to pracował dla mojego samsung ale nie dla LG one.the awarii aplikacji bezpośrednio po zrobieniu zdjęcia zanim zapisać go – bohr

0

Trzeba powiedzieć aparatu do zapisywania ścieżkę obrazu jak poniżej:

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

uwaga: w urządzeniach samsung ** onActivityResult ** nie wezwał działalności CV zamiast tego działanie jest ponownie uruchamiane po wywołaniu z kamery, więc * picurl * może być znowu pusty - możemy użyć ** klasy aplikacji **, aby zachować referencję zmiennej –

+0

dzięki za odpowiedź, jak zainicjować f? – bohr

+0

@ AromalSasidharan nie rozumiem :(jak ja użyć klasy aplikacji? – bohr

0

Spróbuj jeden

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

w niektórych urządzeniach onActivityResult nie wezwał działalności CV zamiast aktywność zostaje wznowiona po oddzwonienia z zamiarem aparatu, więc picurl może być ponownie null - możemy użyć klasy aplikacji, aby zachować odniesienie do zmienna

możemy stworzyć własną klasę aplikacji

1.W android manifestu musimy określić klasę aplikacji mamy zamiar użyć

<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 Klasa Application

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

3.Inside wykorzystanie aktywny

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

Powinny to być 'public Uri getPicUri()', ponieważ nie możesz wrócić z pustką. powinienem nazwać dokładnie setPicUri (aUri)? Po wywołaniu intencji kamery z 'Intent intentPicture = new Intent (MediaStore.ACTION_IMAGE_CAPTURE); \t \t \t \t startActivityForResult (intentPicture, PICK_FROM_CAMERA_EDIT); 'następnym razem mogę kontrolować wszystko jest w bloku onActivityResult – erdomester

0

Mam ten sam problem w mojej aplikacji. Problem polega na tym, że po uruchomieniu funkcji onActivityResult dane są zerowe, więc nie można uzyskać niczego z działania kamery. Powinien istnieć inny sposób rozwiązania tego problemu zamiast korzystania z klasy Application, ponieważ staje się to bardzo skomplikowane, gdy obsługujesz więcej niż jedno zdjęcie.

8

Dla tych, którzy nie mogli rozwiązać tego problemu z żadną z odpowiedzi tutaj, oto sposób.

Masz członka picUri, w którym zapisujesz identyfikator URI pliku tymczasowego przed wywołaniem startActivityForResult w celu uruchomienia aplikacji Aparat.

Po wstrzymaniu aplikacji informacje te mogą zostać utracone (tak jak w moim przypadku), a po powrocie do aktywności będzie można je użyć do uzyskania zapisanego obrazu z aparatu.

Następnie otrzymasz NullPointerException.

Właściwym sposobem na utrzymanie picUri to, aby go uratować i przywrócić go onSaveInstanceState(Bundle)onRestoreInstanceState(Bundle) aby zapobiec utracie informacji.

Oto jak to zrobić:

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

} 

Dał mi ból głowy przez dwie godziny.

+0

Taka odpowiedź klasowa. Pracuj tak dalej – VVB

0

Zobacz, zrobiłem jeszcze coś, może zaoszczędzić twój czas. Chodzi o to, że obiekt danych w onActivityResult() jest główną treścią, na którą należy zwrócić uwagę. Obiekt danych ma wartość null, jeśli chodzi o operowanie kodem p = dla następnego ruchu. To, co zrobisz, to po prostu ustawić warunek if-else i uruchomić swój projekt.

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

Sprawdź to, jest łatwe i wykonasz swoją pracę za jednym razem.