Моя цель - создать XML файл в внутреннем хранилище, а затем отправить его через намерение share.
Я могу создать XML файл, используя этот код
FileOutputStream outputStream = context.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
PrintStream printStream = new PrintStream(outputStream);
String xml = this.writeXml(); // get XML here
printStream.println(xml);
printStream.close();
Я застреваю, пытаясь извлечь Uri в выходной файл, чтобы поделиться им. Сначала я попытался получить доступ к файлу, преобразов файл в Uri
File outFile = context.getFileStreamPath(fileName);
return Uri.fromFile(outFile);
Это возвращает файл:///data/data/com.my.package/files/myfile.xml, но я не могу прикреплять его к электронной почте, загрузке и т.д.
Если я вручную проверю длину файла, это правильно и показывает, что существует разумный размер файла.
Далее я создал поставщика контента и попытался ссылаться на файл, и он не является допустимым дескриптором файла. ContentProvider
никогда не кажется, что он называется любой точкой.
Uri uri = Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/" + fileName);
return uri;
Это возвращает содержимое://com.my.package.provider/myfile.xml, но я проверяю файл и нулевую длину.
Как правильно обращаться к файлам? Нужно ли создавать файл с поставщиком контента? Если да, то как?
Обновление
Вот код, который я использую для совместного использования. Если я выберу Gmail, он будет отображаться как вложение, но когда я отправлю его, вы получите сообщение об ошибке Невозможно показать вложение, и пришедшее письмо не имеет вложения.
public void onClick(View view) {
Log.d(TAG, "onClick " + view.getId());
switch (view.getId()) {
case R.id.share_cancel:
setResult(RESULT_CANCELED, getIntent());
finish();
break;
case R.id.share_share:
MyXml xml = new MyXml();
Uri uri;
try {
uri = xml.writeXmlToFile(getApplicationContext(), "myfile.xml");
//uri is "file:///data/data/com.my.package/files/myfile.xml"
Log.d(TAG, "Share URI: " + uri.toString() + " path: " + uri.getPath());
File f = new File(uri.getPath());
Log.d(TAG, "File length: " + f.length());
// shows a valid file size
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("text/plain");
startActivity(Intent.createChooser(shareIntent, "Share"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
break;
}
}
Я заметил, что изнутри createChooser (...) есть Exception
, но я не могу понять, почему он был брошен.
E/ActivityThread (572): активность com.android.internal.app.ChooserActivity просочился IntentReceiver [email protected], который был первоначально зарегистрированный здесь. Вам не хватает unregisterReceiver()?
Я исследовал эту ошибку и не могу найти ничего очевидного. Обе эти ссылки показывают, что мне нужно отменить регистрацию получателя.
- В ChooserActivity просочился IntentReceiver
- Почему Intent.createChooser() нуждается в BroadcastReceiver и как реализовать?
У меня есть настройка приемника, но для AlarmManager
, которая установлена в другом месте и не требует приложения для регистрации/отмены регистрации.
Код для openFile (...)
В случае необходимости, вот создатель содержимого, который я создал.
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
String fileLocation = getContext().getCacheDir() + "/" + uri.getLastPathSegment();
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);
return pfd;
}