Android11:发送带有自动附加文件的电子邮件
Android 11: Send e-mail with automatically attached file
我想要打开和电子邮件应用程序,其中包含已生成的文本、主题、收件人和附件,它适用于 android SDK 版本 29(android 10)及更低版本。但是从Android 11开始有限制写入外部或内部存储文件,还有另一个限制是不允许从应用程序文件目录自动附加文件。
以前我是从应用程序存储复制到内部或外部存储以附加文件,有什么解决方案吗?
完成
android:requestLegacyExternalStorage="true"
public static void sendMail(Context context) throws IOException {
Context appContext = context.getApplicationContext();
File logFile = FileUtils.createFile(context.getFilesDir().getAbsolutePath(), "testFile.txt", "Test");
File logsDirectory = new File(FileUtils.getStorageDirectory(appContext), "files");
logsDirectory.mkdirs();
File destFile = new File(logsDirectory, "log.txt");
InputStream in = new FileInputStream(logFile);
boolean copied = FileUtils.copyToFile(in, destFile);
Uri logPath = Uri.fromFile(destFile);
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// set the type to 'email'
emailIntent.setData(Uri.parse("mailto:"));
String[] to = {"support@test.com"};
String subject = "Test log";
String body =
"Hello";
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_EMAIL, to);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
// the attachment
emailIntent.putExtra(Intent.EXTRA_STREAM, logPath);
context.startActivity(Intent.createChooser(emailIntent, "Send email..."));
}
public class FileUtils {
public static String getExtensionFromFileName(String fileName) {
if (fileName == null) return null;
String extension = null;
int i = fileName.lastIndexOf('.');
if (i > 0) {
extension = fileName.substring(i + 1);
}
return extension;
}
/**
* Copy data from a source stream to destFile. Return true if succeed, return false if failed.
*/
public static boolean copyToFile(InputStream inputStream, File destFile) {
if (inputStream == null || destFile == null) return false;
try {
try (OutputStream out = new FileOutputStream(destFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) >= 0) {
out.write(buffer, 0, bytesRead);
}
}
return true;
} catch (IOException e) {
Log.e("[File Utils]", "copyToFile exception: " + e);
}
return false;
}
public static String getStorageDirectory(Context mContext) {
String storageDir =
Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/"
+ mContext.getString(R.string.app_name);
File file = new File(storageDir);
mContext.getExternalMediaDirs();
if (!file.isDirectory() || !file.exists()) {
}
return storageDir;
}
public static File createFile(String directory ,String fileName, String textToAttach)
{
File logFile = new File(directory + "/" + fileName);
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(textToAttach);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return logFile;
}
}
我已经使用了 FileProvider 和选择器,这是针对多个文件的
public static void sendMail(Context context) {
Context appContext = context.getApplicationContext();
final String authority = appContext.getPackageName() + ".FileProvider";
String[] to = {"test@test.com"};
String subject = "subject";
String body = "body";
ArrayList<File> logFiles = getLogFile(context);
if (logFiles.size() == 0) {
Toast.makeText(
context,
context.getString(R.string.toast_send_failed_no_file_found),
Toast.LENGTH_LONG)
.show();
return;
}
// has to be an ArrayList
ArrayList<Uri> logPaths = new ArrayList<>();
for (File file : logFiles) {
if (file.exists()) {
logPaths.add(FileProvider.getUriForFile(appContext, authority, file));
}
}
Intent emailSelectorIntent = new Intent(Intent.ACTION_SENDTO);
emailSelectorIntent.setDataAndType(Uri.parse("mailto:"), "plain/text");
final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
// emailIntent.setType("plain/text");
emailIntent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
emailIntent.putExtra(Intent.EXTRA_EMAIL, to);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, logPaths);
emailIntent.setSelector(emailSelectorIntent);
context.startActivity(Intent.createChooser(emailIntent, "Send Logs"));
}
我想要打开和电子邮件应用程序,其中包含已生成的文本、主题、收件人和附件,它适用于 android SDK 版本 29(android 10)及更低版本。但是从Android 11开始有限制写入外部或内部存储文件,还有另一个限制是不允许从应用程序文件目录自动附加文件。 以前我是从应用程序存储复制到内部或外部存储以附加文件,有什么解决方案吗?
完成
android:requestLegacyExternalStorage="true"
public static void sendMail(Context context) throws IOException {
Context appContext = context.getApplicationContext();
File logFile = FileUtils.createFile(context.getFilesDir().getAbsolutePath(), "testFile.txt", "Test");
File logsDirectory = new File(FileUtils.getStorageDirectory(appContext), "files");
logsDirectory.mkdirs();
File destFile = new File(logsDirectory, "log.txt");
InputStream in = new FileInputStream(logFile);
boolean copied = FileUtils.copyToFile(in, destFile);
Uri logPath = Uri.fromFile(destFile);
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// set the type to 'email'
emailIntent.setData(Uri.parse("mailto:"));
String[] to = {"support@test.com"};
String subject = "Test log";
String body =
"Hello";
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_EMAIL, to);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
// the attachment
emailIntent.putExtra(Intent.EXTRA_STREAM, logPath);
context.startActivity(Intent.createChooser(emailIntent, "Send email..."));
}
public class FileUtils {
public static String getExtensionFromFileName(String fileName) {
if (fileName == null) return null;
String extension = null;
int i = fileName.lastIndexOf('.');
if (i > 0) {
extension = fileName.substring(i + 1);
}
return extension;
}
/**
* Copy data from a source stream to destFile. Return true if succeed, return false if failed.
*/
public static boolean copyToFile(InputStream inputStream, File destFile) {
if (inputStream == null || destFile == null) return false;
try {
try (OutputStream out = new FileOutputStream(destFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) >= 0) {
out.write(buffer, 0, bytesRead);
}
}
return true;
} catch (IOException e) {
Log.e("[File Utils]", "copyToFile exception: " + e);
}
return false;
}
public static String getStorageDirectory(Context mContext) {
String storageDir =
Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/"
+ mContext.getString(R.string.app_name);
File file = new File(storageDir);
mContext.getExternalMediaDirs();
if (!file.isDirectory() || !file.exists()) {
}
return storageDir;
}
public static File createFile(String directory ,String fileName, String textToAttach)
{
File logFile = new File(directory + "/" + fileName);
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(textToAttach);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return logFile;
}
}
我已经使用了 FileProvider 和选择器,这是针对多个文件的
public static void sendMail(Context context) {
Context appContext = context.getApplicationContext();
final String authority = appContext.getPackageName() + ".FileProvider";
String[] to = {"test@test.com"};
String subject = "subject";
String body = "body";
ArrayList<File> logFiles = getLogFile(context);
if (logFiles.size() == 0) {
Toast.makeText(
context,
context.getString(R.string.toast_send_failed_no_file_found),
Toast.LENGTH_LONG)
.show();
return;
}
// has to be an ArrayList
ArrayList<Uri> logPaths = new ArrayList<>();
for (File file : logFiles) {
if (file.exists()) {
logPaths.add(FileProvider.getUriForFile(appContext, authority, file));
}
}
Intent emailSelectorIntent = new Intent(Intent.ACTION_SENDTO);
emailSelectorIntent.setDataAndType(Uri.parse("mailto:"), "plain/text");
final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
// emailIntent.setType("plain/text");
emailIntent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
emailIntent.putExtra(Intent.EXTRA_EMAIL, to);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, logPaths);
emailIntent.setSelector(emailSelectorIntent);
context.startActivity(Intent.createChooser(emailIntent, "Send Logs"));
}