#android #android-intent #export-to-csv #fileoutputstream
#java #Android #csv #android-намерение #экспорт в csv
Вопрос:
У меня есть простое приложение для ведения журнала, которое собирает данные в три списка массивов, которые я хочу сохранить в файл CSV, а затем отправить на Google Диск, электронную почту и т. Д.
Вот как я сохраняю данные:
StringBuilder data = new StringBuilder();
data.append("Timestamp,Mass,Change in Massn");
for(int i = 0; i < mass_list.size(); i ){
data.append(String.valueOf(timestamp_list.get(i)) "," String.valueOf(mass_list.get(i)) "," String.valueOf(mass_roc_list.get(i)) "n");
}
FileOutputStream out = openFileOutput("scale.csv", Context.MODE_APPEND );
out.write(data.toString().getBytes());
out.close();
Это просто объединило мои ArrayLists в строку и сохраняет данные в CSV-файл со шкалой имен.
Вот как я пытаюсь поделиться им:
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[{"email@gmail.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Scale Data");
emailIntent.putExtra(Intent.EXTRA_TEXT, "This is the body");
emailIntent.putExtra(Intent.EXTRA_STREAM, Environment.getExternalStorageDirectory() "/scale.csv");
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
Когда я пытаюсь сделать это в электронном письме, вложения нет, только тело. Когда я пытаюсь использовать Google Диск, только тело сохраняется в текстовый файл. Я не уверен, что я делаю неправильно, но, вероятно, это как-то связано с расположением файлов. Может быть, я не могу найти файл, который я сохранил?
Я был бы признателен за любую помощь и готов предоставить разъяснения по запросу.
РЕДАКТИРОВАТЬ с помощью обратной связи
Я попробовал одно из предложенных решений. Вот как выглядит мой код сейчас:
StringBuilder data = new StringBuilder();
data.append("Timestamp,Mass,Change in Massn");
for(int i = 0; i < mass_list.size(); i ){
data.append(String.valueOf(timestamp_list.get(i)) "," String.valueOf(mass_list.get(i)) "," String.valueOf(mass_roc_list.get(i)) "n");
}
try {
//saving data to a file
FileOutputStream out = openFileOutput("scale.csv", Context.MODE_APPEND);
out.write(data.toString().getBytes());
out.close();
Context context = getApplicationContext();
String filename="/scale.csv";
File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
Uri path = FileProvider.getUriForFile(context, "com.example.scaleapp.fileprovider", filelocation);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// set the type to 'email'
emailIntent.setType("vnd.android.cursor.dir/email");
String to[] = {"email.com"};
emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Scale Data");
emailIntent.putExtra(Intent.EXTRA_TEXT, "This is the body");
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// the attachment
emailIntent.putExtra(Intent.EXTRA_STREAM, path);
//this line is where an exception occurs and "Error" is displayed on my phone
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
infoView.setText("Something worked!");
}
catch(Exception e){
e.printStackTrace();
infoView.setText("Error");
}
Все компилируется и работает нормально. Однако, когда я загружаю на диск, он говорит «невозможно загрузить», а когда я отправляю электронное письмо, в нем говорится «невозможно прикрепить пустой файл».
Ответ №1:
Создайте XML-файл в res/xml/provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--
name is the file name
path is the root of external storage, it means here: Environment.getExternalStorageDirectory()
-->
<external-path name="scale" path="."/>
<!--
another example: Environment.getExternalStorageDirectory() File.separator "temps" "myFile.pdf"
-->
<external-path name="myFile" path="temps"/>
</paths>
добавьте поставщика в свой тег приложения в манифесте
<!--android:name="android.support.v4.content.FileProvider"-->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="your.application.package.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
Наконец, измените свой код на это:
public static void sendEmailWithAttachment(Context context) {
String filename="/scale.csv";
File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
//Uri path = Uri.fromFile(filelocation);
Uri path = FileProvider.getUriForFile(context, "your.application.package.fileprovider", filelocation);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// set the type to 'email'
emailIntent .setType("vnd.android.cursor.dir/email");
String to[] = {"email@gmail.com"};
emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Scale Data");
emailIntent.putExtra(Intent.EXTRA_TEXT, "This is the body");
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// the attachment
emailIntent .putExtra(Intent.EXTRA_STREAM, path);
context.startActivity(Intent.createChooser(emailIntent, "Send mail..."));
}
Несколько советов по определению пути к файлу из документов Android
<files-path name="name" path="path" />
Представляет Context.getFilesDir()
<cache-path name="name" path="path" />
Представляет getCacheDir()
<external-path name="name" path="path" />
Представляет Environment.getExternalStorageDirectory().
<external-cache-path name="name" path="path" />
Представляет контекст#getExternalFilesDir(строка) Context.getExternalFilesDir(null)
<external-media-path name="name" path="path" />
Представляет Context.getExternalCacheDir() .
Комментарии:
1. Спасибо за ваш ответ! У меня все еще возникают некоторые проблемы. Я был бы признателен, если бы вы взглянули на мое редактирование.
2. @NickSolonko проблема больше всего заключается в том, как вы создаете свой
.csv
файл. Я протестировал этот код без каких-либо проблем. протестируйте его с другим файлом. (файл, который вы не создаете)3. Я также пробовал использовать текстовый файл, и это не сработало. Я попробую то, что вы предложили
4. Теперь все работает хорошо. Ваш ответ работает для внешнего хранилища, и в итоге я использовал internal, однако это было хорошее начало. Я думаю, что будущим посетителям этого вопроса было бы полезно, если бы вы добавили путь для внутреннего хранилища (
files-path
вместо внешнего). Спасибо!