2015-06-17 14 views
6

Zaktualizowałem wersję systemu operacyjnego Android nexus 5 do wersji 5.1.1, a także zaktualizowałem aplikację Aparat Google i Zdjęcia Google. Po tym, gdy kiedykolwiek próbowałem przechwycić obraz i przyciąć go, moje awarie aplikacji z powodu następującego błędu:Android: Awaria po przycięciu obrazu po zaktualizowaniu wersji systemu operacyjnego do wersji 5.1.1

FATAL EXCEPTION: main 
Process: com.app.test, PID: 4857 
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { typ=image/jpeg }} to activity {com.app.test/com.app.test.newActivity.activities.TestActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Parcelable android.os.Bundle.getParcelable(java.lang.String)' on a null object reference 
     at android.app.ActivityThread.deliverResults(ActivityThread.java:3574) 
     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617) 
     at android.app.ActivityThread.access$1300(ActivityThread.java:151) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5254) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Parcelable android.os.Bundle.getParcelable(java.lang.String)' on a null object reference 
     at com.app.test.newActivity.activities.TestActivity.onActivityResult(TestActivity.java:127) 
     at android.app.Activity.dispatchActivityResult(Activity.java:6192) 
     at android.app.ActivityThread.deliverResults(ActivityThread.java:3570) 
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617) 
            at android.app.ActivityThread.access$1300(ActivityThread.java:151) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:135) 
            at android.app.ActivityThread.main(ActivityThread.java:5254) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:372) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

Wcześniej pracował w porządku. Kod Użyłem jest następujący:

Zdjęcie Kod Przechwytywanie:

try { 
    Intent imageCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    if (imageCapture.resolveActivity(getContext().getPackageManager()) != null) { 
     imageCapture.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + Constants.image_path))); 
     startActivityForResult(imageCapture, Constants.CAMERA_IMAGE_CAPTURE); 
    } 
} catch (ActivityNotFoundException anfe) { 
    Toast.makeText(getContext(), "device doesn't support capturing images!", Toast.LENGTH_SHORT).show(); 
} 

kod Crop Obraz

@Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) { 
     super.onActivityResult(requestCode, resultCode, intent); 
     if (resultCode == RESULT_OK) { 
      if (requestCode == CAMERA_IAMGE_CROP) { 
       Bundle extras = intent.getExtras();//intent.getExtras() is always returns NULL here   
       Bitmap thePic = extras.getParcelable("data"); 
       //setImageOnImageView(thePic); 
      } else if (requestCode == Constants.CAMERA_IMAGE_CAPTURE)) { 
       processCapturedImage(); 
      } 
     } 
    } 

    private void processCapturedImage() { 
     try { 
      String path = Environment.getExternalStorageDirectory().getAbsolutePath() + Constants.image_path; 
      File file = new File(path); 
      if (file.exists()) { 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inPreferredConfig = Bitmap.Config.RGB_565; 
       Bitmap bm = BitmapFactory.decodeFile(path, options); 
       int rotate = AndroidUtils.getRotateValue(file.getAbsolutePath()); 
       if (rotate != 0) { 
        Debug.print("Profile pic rotation value is not 0."); 
        /****** Image rotation ****/ 
        Matrix matrix = new Matrix(); 
        matrix.postRotate(rotate); 
        bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); 
       } 
       picUri = getImageUri(getApplicationContext(), bm); 
       performCropAction(); 
      } else { 
       Tools.showToast(EditProfileActivity.this, "Error occurred, please try again."); 
      } 
     } catch (Exception e) { 
      Debug.printException(e); 
     } 
    } 

    private void performCropAction() { 
     try { 
      Intent cropAction = new Intent("com.android.camera.action.CROP"); 
      cropAction.setDataAndType(picUri, "image/*"); 
      cropAction.putExtra("crop", "true"); 
      cropAction.putExtra("aspectX", 1); 
      cropAction.putExtra("aspectY", 1); 
      cropAction.putExtra("outputX", AS.getInPixels(100)); 
      cropAction.putExtra("outputY", AS.getInPixels(100)); 
      cropAction.putExtra("return-data", true); 
      startActivityForResult(cropAction, CAMERA_IAMGE_CROP); 
     } 
     catch (ActivityNotFoundException anfe) { 
      Toast.makeText(this, "your device doesn't support the crop action!", Toast.LENGTH_SHORT).show(); 
     } 
    } 

Jak widać, Bundle dodatki = intencją. getExtras(); Tutaj intent.getExtras() zawsze zwraca NULL.

Każda pomoc jest naprawdę doceniana! Dzięki.

+1

Android nie ma intencji 'CROP'. Istnieje wiele bibliotek do przycinania obrazu (http://android-arsenal.com/tag/45) dostępnych dla Androida; użyj jednego. – CommonsWare

+1

ale ten sam kod działa poniżej 5.1.1. W wersji 5.1.1 aplikacja ulega awarii z wyjątkiem. {java.lang.RuntimeException: niepowodzenie dostarczania wyniku ResultInfo {who = null, request = 1, result = 0, data = null} to activity {camera.test.demo/camera.test.demo.SimpleCameraGalleryDemo}: java.lang. NullPointerException: Próba wywołania metody wirtualnej "android.os.Bundle android.content.Intent.getExtras()" na odwołaniu do obiektu zerowego} – user1182217

+0

"ale ten sam kod działa poniżej wersji 5.1.1" - istnieje kilka tysięcy modeli urządzeń z Androidem. Czuję się bardzo pewny, że nie testowałeś ich wszystkich, a nawet wielu z nich. Najprawdopodobniej przetestowałeś tylko na jednym lub dwóch z nich. Niechlujni programiści zakładają, że nieudokumentowane, nieobsługiwane i nieoficjalne akcje "Intent" będą obsługiwane na wszystkich urządzeniach. Utalentowani programiści używają biblioteki. – CommonsWare

Odpowiedz

2

Mam ten sam problem. Nowa akcja CROP nie używa metody onActivityResult(). Rozdzielczość: skopiuj plik do folderu, w którym chcesz zapisać przycięty obraz, uruchom "com.android.camera.action.CROP" z skopiowanym wcześniej plikiem. Kiedy użytkownik kliknie przycisk "Zapisz" po przycięciu - nowy skopiowany plik zostanie zastąpiony przyciętym obrazem. Zapytaj mnie, jeśli masz jakieś pytania.

+0

czy możesz wyjaśnić więcej o swoim rozwiązaniu. – nilkash

+0

@nilkash Wszystko gotowe. Możesz sprawdzić nowy komentarz poniżej. –

2

@nikash Rozwiązanie numer jeden: Jeśli chcesz używać tylko aktywność Crop standardowego Androida aparacie, należy wiedzieć, że aktywność przyciąć nowy (Android 5.1.1) Aparat nie robi nic wrócić do onActivityResult metoda(). Po prostu przycina dostarczony obraz. Jeśli dostarczysz Crop Activity z oryginalnym obrazem - zastąpi oryginalny obraz nowym przyciętym. Nie można go zapisać osobno. Możesz utworzyć kopię oryginalnego obrazu (nie umieszczaj tej kopii w folderze danych aplikacji, ponieważ aktywność przycinania kamery nie ma uprawnień do pracy z plikami w folderze aktywności). Po tym możesz wysłać do aktywności przycinania kamery nowe łącze skopiowanego obrazu. Następnie, po przycięciu, możesz przenieść przycięte (przed skopiowaniem) zdjęcie do dowolnego folderu.

Rozwiązanie numer dwa: lepsze niż pierwsze. Możesz użyć tego narzędzia do przycinania obrazu: https://android-arsenal.com/details/1/207

Drugie rozwiązanie jest lepsze niż pierwsze. Łatwy w użyciu, łatwy w implementacji i nie dbasz o błędy innych urządzeń. Będzie działać wszędzie bez standardowej aktywności kamery. Twoja aplikacja może być API7 i nowsza. Nie zapomnij wpisać "compile" com.edmodo: cropper: 1.0.1 '"do pliku gradle. Skompilować. I baw się dobrze.

Przykład użycia: Główna działalność: działalność

Intent cropIntent = new Intent(Main.this, CropActivity.class); 
cropIntent.putExtra("from", input.getAbsolutePath()); 
cropIntent.putExtra("to", output.getAbsolutePath()); 
startActivityForResult(cropIntent, CROP_IMAGE); 

Crop:

Bitmap bmp = BitmapFactory.decodeFile(new File(getIntent().getExtras().getString("from")).getAbsolutePath()); 
cropImageView.setImageBitmap(bmp); 
saveButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       getIntent().putExtra("bitmap", cropImageView.getCroppedImage()); 
       setResult(RESULT_OK, getIntent()); 
       finish(); 
      } 
     }); 

Po można otrzymać go w Główna działalność:

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (resultCode == RESULT_OK && data != null && requestCode == CROP_IMAGE) 
    { 
     croppedBitmap.setImageBitmap((Bitmap) data.getParcelableExtra("bitmap")); 
    } 
} 

Crop układ aktywny Obraz powinien zawierać :

<com.edmodo.cropper.CropImageView 
    xmlns:custom="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/CropImageView" 
    android:layout_centerVertical="true" 
    android:layout_centerHorizontal="true" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    custom:aspectRatioX="5" /> 

Tutaj można znaleźć więcej na temat użycia: https://github.com/edmodo/cropper/wiki

5

Przede android 5.0 funkcji Crop powrotu URI w onActivityResult więc poradzić z wersją telefonu odpowiednio.

Bitmap selectedBitmap; 
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 
Bundle extras = data.getExtras(); 
selectedBitmap = extras.getParcelable("data"); 
} 
else{ 
Uri uri = data.getData(); 
selectedBitmap=MediaStore.Images.Media.getBitmap(this.getContentResolver(),uri); 
} 

Mam nadzieję, że to pomoże!

Powiązane problemy