2016-01-30 2 views
3

Я пытаюсь сфотографировать камеру с собственным устройством. Im», начиная с отправки намерения:Не удается декодировать растровый файл с камеры

private void dispatchTakePictureIntent() { 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    // Ensure that there's a camera activity to handle the intent 
    if (takePictureIntent.resolveActivity(getMainActivity().getPackageManager()) != null) { 
     // Create the File where the photo should go 
     File photoFile = null; 
     try { 
      photoFile = createImageFile(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
     // Continue only if the File was successfully created 
     if (photoFile != null) { 
      takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, 
        Uri.fromFile(photoFile)); 
      startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); 
     } 
    } 
} 

начинается камера, файл создается, я беру фотографию, а затем эта фотография принимается и декодируется с этим кодом:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) { 
     Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath); 

     if (bitmap == null) { 
      Crashlytics.log("Bitmap factory returned null"); 
     } 

     mImageCropper.setBitmapPhoto(bitmap); 
     expand(mMainImage); 
    } 
} 

Это метод, который создает файл и помните, что путь:

private File createImageFile() throws IOException { 
    // Create an image file name 
    @SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    String imageFileName = "JPEG_" + timeStamp + "_"; 
    File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
    File image = File.createTempFile(
      imageFileName, /* prefix */ 
      ".jpg",   /* suffix */ 
      storageDir  /* directory */ 
    ); 
    if (!image.exists()) { 
     Log.e("take photo", "can't create photo file"); 
     Crashlytics.logException(new NullPointerException("Can't read photo from camera")); 
    } else { 
     Log.d("take photo", "photo file created " + image.getPath()); 
    } 

    mCurrentPhotoPath = image.getAbsolutePath(); 
    return image; 
} 

Но иногда я получил ошибку при декодировании растрового изображения:

D/skia: --- SkImageDecoder::Factory returned null 

Когда я перезапускаю устройство (Nexus 5 (6.0 Marshmallow), но это происходит и на других устройствах), первый запуск этой процедуры в порядке, но затем начинают возникать ошибки. Я не могу воспроизвести эту ошибку на genymotion эмулятора (Nexus 5, 5,0)

Update - причины и обходного

кажется, что родное приложение андроид камера возвращает это результат до того, как битовая карта полностью записана в постоянного хранения. Код, который я не горжусь, но до сих пор она работает:

final Handler handler = new Handler(); 

@Override 
public void onActivityResult(final int requestCode, final int resultCode, Intent data) { 
    Runnable decodeRunnable = new Runnable() { 
     int counter = 0; 

     @Override 
     public void run() { 
      if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) { 
       Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath); 

       if (bitmap == null && counter < 20) { 
        handler.postDelayed(this, 200); 
       } 
       mImageCropper.setBitmapPhoto(bitmap); 
       expand(mMainImage); 
      } 
     } 
    }; 
    handler.postDelayed(decodeRunnable, 100); 
} 

Как вы видите, этот метод будет пытаться декодировать растровое изображение до 20 раз с 200 мс перерывах между попытками. Если у вас есть идея, то это будет приветствоваться.

+0

'mCurrentPhotoPath', похоже, не имеет связей с тем, как вы создаете изображение. Что такое 'mCurrentPhotoPath'? – CommonsWare

+0

Я добавил недостающий фрагмент кода - метод createImageFile() – piotrpo

+0

Вы держите это значение через 'onSaveInstanceState()'? Имейте в виду, что ваш процесс может быть прерван, когда выбранное пользователем приложение камеры находится на переднем плане. – CommonsWare

ответ

0

Я создал AsyncTask для решения этой проблемы, пока мы не найдем более элегантный способ справиться с этим. Я решил использовать this one here.

Смежные вопросы