2017-02-11 179 views
1

我一直在嘗試捕獲圖像並調整其大小(以顯示它)並存儲其base64值。BitmapFactory.decodeFile在某些設備上返回null

private String setImageAndReturnBase64String(ImageView imageView) { 

    Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath); 
    bitmap = Bitmap.createScaledBitmap(bitmap, 400, 400, false); 
    imageView.setImageBitmap(bitmap); 

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
    bitmap.compress(Bitmap.CompressFormat.JPEG, 40, byteArrayOutputStream); 
    byte[] byteArray = byteArrayOutputStream.toByteArray(); 

    return Base64.encodeToString(byteArray, Base64.DEFAULT); 
} 

哪裏mCurrentPhotoPath

String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    String imageFileName = "JPG_" + timeStamp + "_"; 
    File image = File.createTempFile(
      imageFileName, /* prefix */ 
      ".jpg",   /* suffix */ 
      storageDir  /* directory */ 
    ); 

    mCurrentPhotoPath = image.getAbsolutePath(); 

storageDir

File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
    if (!(storageDir != null && storageDir.exists())) { 
     if (storageDir != null) { 
      storageDir.mkdir(); 
     } 
    } 

所有必要的權限,並在清單的文件提供者。

但在某些設備BitmapFactory.decodeFile(mCurrentPhotoPath);返回null導致運行時異常。從火力地堡

堆棧跟蹤:

android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3152) 
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2495) 
android.app.ActivityThread.-wrap11 (ActivityThread.java) 
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1354) 
android.os.Handler.dispatchMessage (Handler.java:102) 
android.os.Looper.loop (Looper.java:148) 
android.app.ActivityThread.main (ActivityThread.java:5443) 
java.lang.reflect.Method.invoke (Method.java) 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:728) 
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:618) 
arrow_drop_down 
Caused by java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=null} to activity {com.app.in/com.app.activities.JobCard}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference 
android.app.ActivityThread.deliverResults (ActivityThread.java:3720) 
android.app.ActivityThread.performResumeActivity (ActivityThread.java:3107) 
android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3152) 
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2495) 
android.app.ActivityThread.-wrap11 (ActivityThread.java) 
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1354) 
android.os.Handler.dispatchMessage (Handler.java:102) 
android.os.Looper.loop (Looper.java:148) 
android.app.ActivityThread.main (ActivityThread.java:5443) 
java.lang.reflect.Method.invoke (Method.java) 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:728) 
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:618) 
arrow_drop_down 
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference 
android.graphics.Bitmap.createScaledBitmap (Bitmap.java:636)) 
android.app.Activity.dispatchActivityResult (Activity.java:6442) 
android.app.ActivityThread.deliverResults (ActivityThread.java:3716) 
android.app.ActivityThread.performResumeActivity (ActivityThread.java:3107) 
android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3152) 
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2495) 
android.app.ActivityThread.-wrap11 (ActivityThread.java) 
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1354) 
android.os.Handler.dispatchMessage (Handler.java:102) 
android.os.Looper.loop (Looper.java:148) 
android.app.ActivityThread.main (ActivityThread.java:5443) 
java.lang.reflect.Method.invoke (Method.java) 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:728) 
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:618) 

如何防止這種運行時異常情況發生在某些設備上?

編輯:在實施評論中建議的方法後,這是我一直面臨的。

Exception java.lang.RuntimeException: Unable to resume activity {com.app.in/com.app.activities.Detailed}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=android:fragment:0, request=0, result=-1, data=null} to activity {com.app.in/com.app.activities.Detailed}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference 
android.app.ActivityThread.performResumeActivity (ActivityThread.java:3121) 
android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3152) 
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2495) 
android.app.ActivityThread.-wrap11 (ActivityThread.java) 
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1354) 
android.os.Handler.dispatchMessage (Handler.java:102) 
android.os.Looper.loop (Looper.java:148) 
android.app.ActivityThread.main (ActivityThread.java:5443) 
java.lang.reflect.Method.invoke (Method.java) 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:728) 
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:618) 

Caused by java.lang.RuntimeException: Failure delivering result ResultInfo{who=android:fragment:0, request=0, result=-1, data=null} to activity {com.app.in/com.app.activities.Detailed}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference 
android.app.ActivityThread.deliverResults (ActivityThread.java:3720) 
android.app.ActivityThread.performResumeActivity (ActivityThread.java:3107) 
android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3152) 
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2495) 
android.app.ActivityThread.-wrap11 (ActivityThread.java) 
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1354) 
android.os.Handler.dispatchMessage (Handler.java:102) 
android.os.Looper.loop (Looper.java:148) 
android.app.ActivityThread.main (ActivityThread.java:5443) 
java.lang.reflect.Method.invoke (Method.java) 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:728) 
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:618) 

Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference 
com.app.fragments.ModeDetailsFragment.setImageAndReturnBase64String (ModeDetailsFragment.java:224) 
com.app.fragments.ModeDetailsFragment.onActivityResult (ModeDetailsFragment.java:198) 
android.app.Activity.dispatchActivityResult (Activity.java:6466) 
android.app.ActivityThread.deliverResults (ActivityThread.java:3716) 
android.app.ActivityThread.performResumeActivity (ActivityThread.java:3107) 
android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3152) 
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2495) 
android.app.ActivityThread.-wrap11 (ActivityThread.java) 
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1354) 
android.os.Handler.dispatchMessage (Handler.java:102) 
android.os.Looper.loop (Looper.java:148) 
android.app.ActivityThread.main (ActivityThread.java:5443) 
java.lang.reflect.Method.invoke (Method.java) 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:728) 
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:618) 

改進方法

private String setImageAndReturnBase64String(ImageView imageView) { 

    Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath); 
    if(bitmap == null) { 
     // First decode with inJustDecodeBounds=true to check dimensions 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(mCurrentPhotoPath, options); 
     // Calculate inSampleSize 
     options.inSampleSize = calculateInSampleSize(options, 400, 400); 
     // Decode bitmap with inSampleSize set 
     options.inJustDecodeBounds = false; 
     bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, options); 
    } else { 
     bitmap = Bitmap.createScaledBitmap(bitmap, 400, 400, false); 
    } 
    imageView.setImageBitmap(bitmap); 
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
    bitmap.compress(Bitmap.CompressFormat.JPEG, 40, byteArrayOutputStream); 
    byte[] byteArray = byteArrayOutputStream.toByteArray(); 

    return Base64.encodeToString(byteArray, Base64.DEFAULT); 
} 

private int calculateInSampleSize(
     BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) >= reqHeight 
       && (halfWidth/inSampleSize) >= reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 

    return inSampleSize; 
} 
+1

我的猜測是您的堆空間不足。而不是在整個圖像中讀取,然後縮小它,使用'BitmapFactory.Options'和'inSampleSize'來讀取一個縮小的圖像,並使用較少的內存。 – CommonsWare

+0

VM免費:7.21MB VM總:19.58MB VM最大:96MB 電池電量:71% 製造商:LG電子 型號:LG-K420 局:Msm8916 Android的API:22 Android操作系統5.1.1 品牌:Lge 內存:1.86GB 這是崩潰期間的設備數據。 –

+0

@CommonsWare你可以看看這個問題嗎? –

回答

0

BitmapFactory.decodeFile()將返回null如果Bitmap會變得太大可用內存。你可以每週在這個網站上閱讀這個'功能'。

只需嘗試一個較小的圖像。

相關問題