Android Создание резидентного входного файла памяти, который может быть прикреплен к электронной почте
Конечная цель будет понятна в ближайшее время.
Я хочу создать файл-объект и вместо того, чтобы получать данные из реального физического файла, я хочу сам предоставить буфер.
Затем я хочу использовать этот файл, который на самом деле не существует в SD-карте или где-либо вне моего приложения, дайте ему имя и отправьте его по электронной почте в виде вложения (используя EXTRA_STREAM).
Я нашел следующий бит кода: Adriaan Koster (@adriaankoster), пост Write byte [] для файла в Java
// convert byte[] to File
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
File fileFromBytes = (File) ois.readObject();
bis.close();
ois.close();
System.out.println(fileFromBytes);
Я использовал его для создания этой функции
private File fileFromBytes(byte[] buf) {
File f = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(buf);
ObjectInputStream ois = new ObjectInputStream(bis);
f = (File) ois.readObject();
bis.close();
ois.close();
}
catch (Exception e) {}
return f;
}
и вот где я застреваю, потому что когда я его использую:
// When sent as body the mail is sent OK
// emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, dump());
// When I try to attach the mail is empty
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, fileFromBytes(dump().getBytes()));
Я знаю из примеров, которые я видел, второй аргумент должен быть URI, но: Как создать URI виртуальный, чтобы соответствовать моему файлу?
EDIT:
Возможность прикрепления данных непосредственно из приложения важна для определенных приложений. А именно, приложения безопасности и банковского обслуживания, которые не хотят слишком сильно перемещать конфиденциальные данные. Разумеется, если данные не доходят до SD-карты и переходят непосредственно в почтовую вставку, ее сложнее нюхать, чем в памяти приложения.
Это не мой конкретный случай, но я хотел бы указать, что эта возможность важна.
Ответы
Ответ 1
Первое, что вы захотите сделать, я думаю, это создать ContentProvider. Вы можете увидеть пример реализации здесь
https://github.com/dskinner/AndroidWeb/blob/master/src/org/tsg/web/WebContentProvider.java
где в приведенном выше примере ссылки вы добавили бы это в свой AndroidManifest.xml
<provider
android:name="org.tsg.web.WebContentProvider"
android:authorities="your.package.name" />
Теперь у вас будет доступный uri для контента, content://your.package.name/
.
Часть вышеприведенного ContentProvider, которого вы заинтересовали, я полагаю, это метод openFile
. При совместном использовании данных по намерениям в приложениях ожидаются определенные вещи. В вашем случае вы хотите поделиться некоторыми байтовыми данными, которые должны быть прикреплены к электронной почте.
Итак, если вы передадите контент uri в приложение электронной почты, например content://your.package.name/foo
, с соответствующими флагами намерений, тогда openFile
будет вызываться на вашем ContentProvider. В этом случае вы можете проверить конец сегмента uri, чтобы увидеть, что запрос foo
был запрошен, и вернуть его соответствующим образом.
Следующая проблема, которую вы вызываете, - это отсутствие файла на диске. Хотя я не могу ручаться за метод, который вы использовали выше (хотя он выглядит кошерным), то, что вам нужно вернуть, это ParcelFileDescriptor
из вашего ContentProvider. Если вы посмотрите на ссылку, которую я предоставил, вы можете попробовать использовать это как образец, чтобы получить дескриптор файла из вашего объекта File
(мои знания об отказе здесь), но я полагаю, что данные просто не будут доступны в этом пункте.
То, что вы делаете, это безопасность. Важно отметить, что вы можете записывать данные на диск конфиденциально, так что только приложение имеет доступ к данным. Я полагаю, но вы можете дважды проверить это, если эти данные являются приватными для приложения, вы можете открыть его через ContentProvider и, возможно, заблокировать, кто и как поставщик будет использоваться, кто может его назвать и т.д. Вы можете захотите вникнуть в андроидные документы для этой части или посмотреть на некоторые другие вопросы SO.
В любом случае, удачи.
Ответ 2
Создайте файл в каталоге кэша приложений. Он будет создан во внутренней файловой системе. Используйте API getCacheDir() для получения пути к директории кеша. Запишите данные в этот каталог, а затем получите URI из объекта File с помощью "Uri.fromFile(File file)". Когда вы закончите с файлом, удалите его.
Кэш приложений доступен только для вашего приложения, следовательно, он безопасен для использования в ваших целях.
Вы можете сделать некоторое шифрование, если данные слишком критичны.
Ответ 3
Я думаю, для этого вам придется разоблачить ContentProvider, который позволит вам обрабатывать URI. Затем приложение электронной почты должно открытьInputStream в вашем URI, после чего вы возвращаете InputStream в свои данные в памяти.
Я не пробовал, но теоретически это должно работать.
Ответ 4
Я был занят добавлением вложения в почту, и я могу отправлять почту с приложением.
если вы хотите взглянуть: не может отправлять почту с приложением в Android