Как получить результат камеры в виде uri в папке данных?

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

Я открываю камеру с помощью намерения android.provider.MediaStore.ACTION_IMAGE_CAPTUREи передаю Uri файла в качестве параметра EXTRA_OUTPUT, чтобы вернуть изображение обратно в файл. Это работает отлично, и я могу получить захваченное изображение, если я использую uri внешнего хранилища как EXTRA_OUTPUT , но если я использую uri папки данных, это не работает, и камера не закрывается и все кнопки не работают.

Вот мой код для получения результата во внешнем каталоге хранилища

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File out = Environment.getExternalStorageDirectory();
out = new File(out, imagename);
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
startActivityForResult(i, CAMERA_RESULT);

А этот код для получения изображения в папке данных

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File out = getFilesDir();
out = new File(out, MyPharmacyOptions.PRESCRIPTION_IMAGE_NAME);
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
startActivityForResult(i, CAMERA_RESULT);

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

Вот мой класс предоставления контента

public class MyContentProvider extends ContentProvider {
    private static final String Tag = RingtonContentProvider.class.getName();
    public static final Uri CONTENT_URI = Uri
            .parse("content://x.y.z/");
    private static final HashMap<String, String> MIME_TYPES = new HashMap<String, String>();

    static {
        MIME_TYPES.put(".mp3", "audio/mp3");
        MIME_TYPES.put(".wav", "audio/mp3");
        MIME_TYPES.put(".jpg", "image/jpeg");
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public String getType(Uri uri) {
        String path = uri.toString();

        for (String extension : MIME_TYPES.keySet()) {
            if (path.endsWith(extension)) {
                return (MIME_TYPES.get(extension));
            }
        }

        return (null);
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode)
            throws FileNotFoundException {
        File f = new File(getContext().getFilesDir(), uri.getPath());

        if (f.exists()) {
            return (ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY));
        }

        throw new FileNotFoundException(uri.getPath());
    }

    @Override
    public Cursor query(Uri url, String[] projection, String selection,
            String[] selectionArgs, String sort) {
        throw new RuntimeException("Operation not supported");
    }

    @Override
    public Uri insert(Uri uri, ContentValues initialValues) {
        File file = new File(getContext().getFilesDir(), uri.getPath());
        if(file.exists()) file.delete();
        try {
            file.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return Uri.fromFile(file);
    }

    @Override
    public int update(Uri uri, ContentValues values, String where,
            String[] whereArgs) {
        throw new RuntimeException("Operation not supported");
    }

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        File f = new File(getContext().getFilesDir(), "image1.jpg");
        if(f.exists()) f.delete();
        f = new File(getContext().getFilesDir(), "image2.jpg");
        if(f.exists()) f.delete();

        getContext().getContentResolver().notifyChange(CONTENT_URI, null);

    }
}

Итак, чтобы использовать этот контент, я использую следующий код для передачи uri активности камеры

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Uri uri = MyContentProvider.CONTENT_URI;
uri = Uri.withAppendedPath(uri, imagename);
getContentResolver().insert(uri, null);
getContentResolver().notifyChange(RingtonContentProvider.CONTENT_URI, null);
Log.d(Tag, uri.toString());
i.putExtra(MediaStore.EXTRA_OUTPUT, uri);

startActivityForResult(i, CAMERA_RESULT);

Теперь, если я передам URL-адрес, отличный от внешнего каталога хранения, камера открывается, но в эмуляторе он не закрывается, а в устройстве камера закрывается, но я не получаю результата.

Я объявил этот контент в файле манифеста.

<provider
android:name=".contentproviders.MyContentProvider"
android:authorities="x.y.z" />

Также я дал разрешение на запись во внешнее хранилище, а также на использование камеры.

Я могу захватить изображение, используя внешнее хранилище, но я хочу сохранить изображение в каталоге данных, а не во внешнем хранилище, потому что, если внешнее хранилище недоступно, я хочу захватить изображение и отправить письмо.

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

Если мы не предоставим дополнительные функции с намерением камеры, она вернет изображение в виде byte[] в результате действия в качестве дополнительных данных, но это для миниатюры, поэтому я не могу получить изображение с высоким разрешением. используя этот способ.

65
задан CopsOnRoad 6 March 2018 в 07:34
поделиться