Я создаю приложение, в котором хочу сделать снимок, а затем отправить это изображение по электронной почте в виде вложения.
Я открываю камеру с помощью намерения 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[] в результате действия в качестве дополнительных данных, но это для миниатюры, поэтому я не могу получить изображение с высоким разрешением. используя этот способ.