2015-06-17 17 views
6

Tôi đã cập nhật phiên bản hệ điều hành Android Nexus 5 lên 5.1.1 và cũng đã cập nhật ứng dụng Google Máy ảnh và Google Photos. Sau này, khi đã bao giờ tôi đã cố gắng để nắm bắt hình ảnh và Cắt nó, treo ứng dụng của tôi với các lỗi sau:Android: Sự cố sau khi Cắt hình ảnh khi cập nhật Hệ điều hành Phiên bản thành 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) 

Trước đây người ta làm việc tốt. Mã Tôi đã sử dụng như sau:

Chụp ảnh mã:

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

ảnh Crop đang

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

Như bạn thấy, extras Bundle = ý định. getExtras(); intent.getExtras() ở đây luôn trả về NULL.

Bất kỳ trợ giúp nào thực sự được đánh giá cao! Cảm ơn.

+1

Android không có 'CROP'' Intent'. Có rất nhiều [thư viện cắt ảnh] (http://android-arsenal.com/tag/45) có sẵn cho Android; xin vui lòng sử dụng một. – CommonsWare

+1

nhưng cùng một mã hoạt động bên dưới 5.1.1. Trong 5.1.1 ứng dụng bị treo với ngoại lệ. {java.lang.RuntimeException: Không cung cấp kết quả ResultInfo {who = null, request = 1, result = 0, data = null} đến hoạt động {camera.test.demo/camera.test.demo.SimpleCameraGalleryDemo}: java.lang. NullPointerException: Cố gắng gọi phương thức ảo 'android.os.Bundle android.content.Intent.getExtras()' trên tham chiếu đối tượng null} – user1182217

+0

"nhưng cùng một mã hoạt động bên dưới 5.1.1" - có vài nghìn mẫu thiết bị Android. Tôi cảm thấy rất tự tin rằng bạn đã không thử nghiệm trên tất cả chúng, hoặc thậm chí nhiều người trong số họ. Nhiều khả năng, bạn đã thử nghiệm trên chỉ một hoặc hai trong số họ. Các nhà phát triển cẩu thả cho rằng các hành động 'Intent' không chính thức, không được hỗ trợ và không chính thức sẽ được hỗ trợ trên tất cả các thiết bị. Các nhà phát triển tài năng sử dụng thư viện. – CommonsWare

Trả lời

2

Tôi có cùng một vấn đề. Hành động CROP mới không sử dụng phương thức onActivityResult(). Độ phân giải: sao chép tệp vào thư mục mà bạn muốn lưu hình ảnh đã cắt, bắt đầu "com.android.camera.action.CROP" với tệp được sao chép trước đó. Khi người dùng nhấp vào nút "Lưu" sau khi cắt - tệp được sao chép mới sẽ được thay thế bằng hình ảnh đã cắt. Hãy hỏi tôi nếu bạn có bất kỳ câu hỏi nào.

+0

bạn có thể giải thích thêm về giải pháp của mình không. – nilkash

+0

@nilkash Tất cả đã xong. Bạn có thể kiểm tra bình luận mới dưới đây. –

2

@nikash Giải pháp số một: Nếu bạn chỉ muốn sử dụng hoạt động Crop của Máy ảnh Android chuẩn, bạn nên biết hoạt động cắt của máy ảnh mới (Android 5.1.1) không trả về bất kỳ thứ gì cho phương thức onActivityResult(). Nó chỉ cắt hình ảnh bạn cung cấp. Nếu bạn sẽ cung cấp Crop Activity với hình ảnh gốc - nó sẽ thay thế hình ảnh gốc bằng hình ảnh mới được cắt. Nó không thể lưu nó một cách riêng biệt. Bạn có thể tạo bản sao của ảnh gốc (không đặt bản sao này vào thư mục dữ liệu của ứng dụng của bạn, vì hoạt động cắt của Máy ảnh không có quyền để làm việc với bất kỳ tệp nào trong thư mục hoạt động của bạn). Sau đó, bạn có thể gửi cho hoạt động cắt của Máy ảnh liên kết mới của hình ảnh được sao chép. Sau đó, sau khi cắt xén, bạn có thể di chuyển ảnh đã cắt (trước khi sao chép) sang bất kỳ thư mục nào bạn muốn.

Giải pháp thứ hai: Tốt hơn lần đầu tiên. Bạn có thể sử dụng trình cắt hình ảnh này: https://android-arsenal.com/details/1/207

Giải pháp thứ hai tốt hơn giải pháp đầu tiên. Dễ sử dụng, dễ triển khai và bạn không quan tâm đến các lỗi thiết bị khác. Nó sẽ hoạt động ở mọi nơi mà không có Hoạt động Crop của Camera chuẩn. Ứng dụng của bạn có thể là API7 trở lên. Đừng quên đặt "compile" com.edmodo: cropper: 1.0.1 '"vào tệp gradle của bạn. Biên dịch. Và tận hưởng.

sử dụng Ví dụ: hoạt động chính: Hoạt động

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

Sau khi bạn có thể nhận được nó trong hoạt động chính:

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 bố trí Hoạt động Hình ảnh nên chứa :

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

Ở đây bạn có thể tìm thêm về cách sử dụng: https://github.com/edmodo/cropper/wiki

5

Trên chức năng 5.0 Crop android trở URI trong onActivityResult để xử lý nó với phiên bản của điện thoại cho phù hợp.

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

Hy vọng điều này sẽ hữu ích!

Các vấn đề liên quan