2012-06-28 3 views
1

일부 휴대 전화에서는 Android 앱이 작동하지 않지만 다른 휴대 전화에서는 작동하지 않습니다. 그것은 약 5k 다운로드를 가지고 있으며, 지금까지 약 50 가지의 충돌 보고서를 받았습니다. 그러나 사용자의 평점/의견에 따르면 사용자가 강제로 중단된다고 말하면서 영향을받는 사용자의 비율이 실제로 훨씬 높다고 생각합니다.사진을 SD 카드에 저장하는 중 Android 오류가 발생했습니다.

문제가 내 전화에 영향을 미치지 않으므로 오류를 재현하고 디버깅 할 수 없습니다.

앱이 카메라에서 사진을 찍은 다음 비트 맵 위에 오버레이하여 결과 이미지를 SD 카드에 저장합니다.

다음은 onPictureTaken PictureCallback 메서드에 대한 코드입니다. 다음과 같이

private Camera.PictureCallback mPicture = new Camera.PictureCallback() { 

    public void onPictureTaken(byte[] data, Camera camera) { 

     captureBtn.setVisibility(ImageButton.INVISIBLE); 

     File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); 
     if (pictureFile == null){ 
      return; 
     } 

     BitmapFactory.Options options = new BitmapFactory.Options(); 
     Bitmap mutableBitmap = null; 
     Bitmap finalBitmap = null; 
     byte[] byteArray = null; 
     try { 
      mutableBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options).copy(Bitmap.Config.RGB_565, true); 
      Matrix matrix = new Matrix(); 
      int width = mutableBitmap.getWidth(); 
      int height = mutableBitmap.getHeight(); 
      int newWidth = overlayView.getDrawable().getBounds().width(); 
      int newHeight = overlayView.getDrawable().getBounds().height(); 
      float scaleWidth = ((float) newWidth)/width; 
      float scaleHeight = ((float) newHeight)/height; 
      matrix.postScale(scaleWidth, scaleHeight); 
      matrix.postRotate(90); 

      Bitmap resizedBitmap = Bitmap.createBitmap(mutableBitmap, 0, 0, mutableBitmap.getWidth(), mutableBitmap.getHeight(), matrix, true); 
      finalBitmap = resizedBitmap.copy(Bitmap.Config.RGB_565, true); 
      Canvas canvas = new Canvas(finalBitmap); 

      Bitmap overlayBitmap = null; 
      if (mWeaponType == wep1) { 
       overlayBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.wep1); 
      } else if (mWeaponType == wep2) { 
       overlayBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.wep2); 
      } 

      if (overlayBitmap != null) { 

       matrix = new Matrix(); 
       matrix.postRotate(90); 
       Bitmap resizedOverlay = Bitmap.createBitmap(overlayBitmap, 0, 0, overlayBitmap.getWidth(), overlayBitmap.getHeight(), matrix, true); 
       canvas.drawBitmap(resizedOverlay, 0, 0, new Paint()); 
       canvas.scale(50, 0); 
       canvas.save(); 
       //finalBitmap is the image with the overlay on it 

       // rotate image to save in landscape mode 
       matrix = new Matrix(); 
       matrix.postRotate(270); 
       finalBitmap = Bitmap.createBitmap(finalBitmap, 0, 0, finalBitmap.getWidth(), finalBitmap.getHeight(), matrix, 
         true); 

       // convert final bitmap to byte array 
       ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
       finalBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); 
       byteArray = stream.toByteArray(); 
      } 
     } 

     catch(OutOfMemoryError e) { 
      //fail 
     } 

     try { 
       FileOutputStream fos = new FileOutputStream(pictureFile); 
       fos.write(byteArray); 
       fos.close(); 

       // Notify system that SD card has been updated 
       sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory()))); 
       Log.i(TAG, "Picture saved, intent broadcast that SD has been updated"); 
     } catch (FileNotFoundException e) { 
      Log.d(TAG, "File not found: " + e.getMessage()); 
     } catch (IOException e) { 
      Log.d(TAG, "Error accessing file: " + e.getMessage()); 
     } catch (NullPointerException e) { 

     } 

     finally { 
      mCamera.startPreview(); 
      captureBtn.setVisibility(ImageButton.VISIBLE); 
     } 
    } 
}; 

나는 NullPointerException이 얻을 :

java.lang.NullPointerException 
at java.io.FileOutputStream.write(FileOutputStream.java:256) 
at com.mypackage.MyActivity.onPictureTaken(MyActivity.java:215) 

fos.write(byteArray); 

라인이다.

/** Create a File for saving an image or video */ 
private static File getOutputMediaFile(int type){ 
    // To be safe, you should check that the SDCard is mounted 
    // using Environment.getExternalStorageState() before doing this. 

    File mediaStorageDir = Environment.getExternalStoragePublicDirectory(
       Environment.DIRECTORY_PICTURES); 

    // Create the storage directory if it does not exist 
    if (! mediaStorageDir.exists()){ 
     if (! mediaStorageDir.mkdirs()){ 
      Log.d("HalfLife2 Booth", "failed to create directory"); 
      return null; 
     } 
    } 

    // Create a media file name 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    File mediaFile; 
    if (type == MEDIA_TYPE_IMAGE){ 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
     "IMG_"+ timeStamp + ".jpg"); 
    } else if(type == MEDIA_TYPE_VIDEO) { 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
     "VID_"+ timeStamp + ".mp4"); 
    } else { 
     return null; 
    } 

    return mediaFile; 
} 

내가 문제가 어딘가에 여기에있을 수 있다고 생각, 출력 미디어 파일을 얻으려고 노력에서 다음과 같이

위에 나열된 getOutputMediaFile 방법이다. 내가 사용하는 응용 프로그램을 업데이트 시도했다 :

File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
       Environment.DIRECTORY_PICTURES), "MyApp"); 
대신

, 한 사용자가 해결 될 수있는 문제를보고했지만, 몇은 계속보고있다.

의견이 있으십니까? 내가 복제하거나 근처에 어디서나 얻을 수 없을 때 디버깅/수정이 까다로운 하나를 찾는거야.

+0

메이크업에 null이 전달되도록 예외는 당신이 OutOfMemorryError을 치는 것을 제안 추적과 같은 BYTEARRAY이 채워되지지고 결코로 제공 매니 페스트에서 을 사용하십시오. –

+0

권한이 설정되지 않은 경우 모든 휴대 전화에서 문제가 발생한다고 생각합니다. –

+0

맞습니다. 사용 권한이 올바르게 설정되었습니다. – breadbin

답변

2

사진을 원시 형식으로 조정해야합니다. 나는 일부 휴대폰 모델에서 원시 이미지가 거대하다는 것을 발견했다. 가상 시스템을 메모리 부족으로 실행하기 때문에 이미지가 매우 큰 경우 이미지 크기를 조정하는 것이 좋습니다.

예 :

 imageRef = sd_card_path+"/"+ImageName; 
       BitmapFactory.Options resample = new BitmapFactory.Options(); 
       resample.inJustDecodeBounds = true; 
       BitmapFactory.decodeFile(imageRef, resample); 
       int width = resample.outWidth; 
       int height = resample.outHeight; 
       if(width*height > utility.IMAGE_SIZE_MIN){ 
        int imageSizef = (int)(width*height/utility.IMAGE_SIZE_MIN); 
        String imageSize = imageSizef+""; 
        resample.inSampleSize = Integer.parseInt(imageSize); 
        resample.inJustDecodeBounds = false; 
        image.setImageBitmap(BitmapFactory.decodeFile(imageRef , resample));      
       }else{ 
        image.setImageBitmap(BitmapFactory.decodeFile(imageRef)); 
       } 
+0

의견을 보내 주셔서 감사합니다. 어떻게 달성 할 수 있을까요? – breadbin

+0

예제에서 파일을 사용한다는 것을 알고 있습니다. 여기서는 카메라 스트림의 직선이 있습니다 : 비트 맵 bitmap = BitmapFactory.decodeByteArray (image, 0, image.length, resample); –

+0

Android Addict에게 감사드립니다. "유틸리티"개체가 무엇인지 물어보고 "IMAGE_SIZE_MIN"값의 출처를 알려주세요. – breadbin

1

당신이 fos.write 방법

+0

이것이 맞습니다, 허용 된 답변에 문제에 대한 자세한 설명이 있습니다. 도와 줘서 고마워. – breadbin

관련 문제