Приложение камеры не записывает изображение во второй раз - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь открыть намерение камеры и загрузить захваченное изображение в Android. Проблема заключается в том, что приложение камеры правильно записывает во входной URI, и записанные данные могут быть успешно декодированы в битовую карту только при первом вызове . При последующих вызовах он не записывает байты во входной файл, и я проверил, что файл, расположенный по этому URI, все еще имеет 0 байтов после того, как управление вернулось из приложения камеры.

Вот код для создания файла URI для ввода в приложение камеры.

private @NonNull Uri getImageUri() {
    Uri outputFileUri = null;

    final String imageFileName = "JPEG_"
        + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".jpeg" ;

    File imagePath = new File(getFilesDir(), "images");

    if(!imagePath.isDirectory()) {
        imagePath.mkdirs();
    }

    File newFile = new File(imagePath, imageFileName);

    if (newFile.exists()) {
        newFile.delete();
    }
    try {
        if(!newFile.createNewFile())
            Log.e(MyActivity.class.getSimpleName(), "Error creating file");

    } catch (IOException e) {
        e.printStackTrace();
    }
    if(!(null != newFile && newFile.isFile())) {
        throw new IllegalStateException("Cannot create file ");
    }
    outputFileUri = FileProvider.getUriForFile(
        this.getApplicationContext(), "com.myapp.android.fileprovider", newFile);


    if(null == outputFileUri){
        throw new IllegalStateException( "Cannot create file for clicking image");
    }

    Log.e(MyActivity.class.getSimpleName(), "output file uri " + outputFileUri);

    return outputFileUri;

}

Ниже приведен код, который открывает намерение камеры:

private List<Intent> getCameraIntents(@NonNull final Uri path){

    if(!mCameraIntents.isEmpty()) return mCameraIntents;

    @NonNull final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    @NonNull final List<ResolveInfo> listCam =
            getPackageManager().queryIntentActivities(captureIntent, 0);

    @NonNull final ArrayList<Intent> cameraIntents = new ArrayList<>(1);
    for (ResolveInfo res : listCam) {
        Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(res.activityInfo.packageName);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, path);
        cameraIntents.add(intent);
    }

    mCameraIntents.addAll(cameraIntents);
    return cameraIntents;
}

/**
 * Create a chooser intent to select the source to get image from.<br />
 * The source can be camera's (ACTION_IMAGE_CAPTURE) or gallery's (ACTION_GET_CONTENT).<br />
 * All possible sources are added to the intent chooser.
 */
private Intent imageChooser() {

    // Determine Uri of camera image to save.
    @NonNull final Uri outputFileUri = getImageUri();

    @NonNull final List<Intent> allIntents = getCameraIntents(outputFileUri);
    allIntents.addAll(getGalleryIntents());

    @NonNull final Intent mainIntent = allIntents.remove(allIntents.size() - 1);


    // Create a chooser from the main intent
    Intent chooserIntent = Intent.createChooser(
            mainIntent,
            getResources().getString(R.string.snap_app_chooser_message));

    // Add all other intents
    chooserIntent.putExtra(
            Intent.EXTRA_INITIAL_INTENTS,
            allIntents.toArray(new Parcelable[allIntents.size()]));

    mSnapUri = outputFileUri;
    return chooserIntent;
}

Тогда я просто называю это, startActivityForResult(imageChooser(), REQUEST_IMAGE_CAPTURE);

Ниже приведен код для декодирования захваченного изображения, записанного в файле URI приложением камеры.

@NonNull @Override protected Bitmap doInBackground(@NonNull final Uri... snapUris) {

    Bitmap snap = null;
    try {
        Log.e(MyActivity.class.getSimpleName(), "snap uri " + snapUris[0]);

        snap = MediaStore.Images.Media.getBitmap(
               mActivity.get().getContentResolver(),
               snapUris[0]);
        if(null == snap ){
            InputStream is = 
                mActivity.get().getContentResolver()
                .openInputStream(snapUris[0]);
            snap = BitmapFactory.decodeStream(is);
        }
        if (null == snap) {
            Log.e(MyActivity.class.getSimpleName(), "Problem with uri path");
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        return snap;
    }

}

Может ли кто-нибудь помочь мне понять, почему приложение камеры не записывает захваченное изображение в URI файла после первого вызова? Что меняется между первым вызовом камеры и следующим вызовом, когда она не может записать во второй и последующие URI файлов. Не выводится ли выходной поток приложения камеры после первого вызова должным образом?

Я протестировал его на телефонах Xiaomi и Lenovo, и у меня аналогичное поведение

...