Java Android 11:发送带有自动附加文件的电子邮件
我想打开和电子邮件应用程序与已经生成的文本,主题,收件人和附加文件,它与安卓sdk版本29(安卓10)和更低。然而,启动Android 11时,在外部或内部存储器中写入文件有限制,并且还有另一个限制,即不允许从应用程序文件目录自动附加文件。 以前我从应用程序存储复制到内部或外部存储以附加文件,有解决方案吗 完成Java Android 11:发送带有自动附加文件的电子邮件,java,android,email-attachments,permission-denied,android-11,Java,Android,Email Attachments,Permission Denied,Android 11,我想打开和电子邮件应用程序与已经生成的文本,主题,收件人和附加文件,它与安卓sdk版本29(安卓10)和更低。然而,启动Android 11时,在外部或内部存储器中写入文件有限制,并且还有另一个限制,即不允许从应用程序文件目录自动附加文件。 以前我从应用程序存储复制到内部或外部存储以附加文件,有解决方案吗 完成 android:requestLegacyExternalStorage=“true” 我已经使用了FileProvider和selector,这是针对多个文件的 public stat
android:requestLegacyExternalStorage=“true”
我已经使用了FileProvider和selector,这是针对多个文件的
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"));
}
publicstaticvoidsendmail(上下文){
Context-appContext=Context.getApplicationContext();
最终字符串权限=appContext.getPackageName()+“.FileProvider”;
字符串[]到={”test@test.com"};
字符串subject=“subject”;
字符串body=“body”;
ArrayList logFiles=getLogFile(上下文);
如果(logFiles.size()==0){
Toast.makeText(
上下文
context.getString(R.string.toast\u发送\u失败\u未找到\u文件),
吐司长度(长)
.show();
返回;
}
//必须是ArrayList
ArrayList日志路径=新的ArrayList();
用于(文件:日志文件){
if(file.exists()){
添加(FileProvider.getUriForFile(appContext,authority,file));
}
}
Intent emailSelectorIntent=新的意图(Intent.ACTION\u SENDTO);
emailSelectorIntent.setDataAndType(Uri.parse(“mailto:”),“纯/文本”);
最终意图emailIntent=新意图(Intent.ACTION\u SEND\u MULTIPLE);
//emailIntent.setType(“纯/文本”);
emailIntent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
emailIntent.putExtra(Intent.EXTRA_电子邮件,收件人);
emailIntent.putExtra(Intent.EXTRA_SUBJECT,SUBJECT);
emailIntent.putExtra(Intent.EXTRA_文本,正文);
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_流,日志路径);
emailIntent.setSelector(EmailSelectorContent);
context.startActivity(Intent.createChooser(emailIntent,“发送日志”);
}
Uri.fromFile(destFile)
已经被禁止五年了——你应该被禁止。使用FileProvider
与其他应用程序共享内容。@Commonware在android 11中只有此异常:E/[File Utils]:copyToFile异常:java.io.FileNotFoundException:/storage/emulated/0/MyApplication/files/log.txt:open失败:enoint(没有这样的文件或目录)这是因为您在StrictMode
中禁用了对FileUriExposedException
的检查。使用FileProvider
与其他应用程序共享内容。您解决了问题吗?@AlexS是的,我按照评论中的建议使用了FileProvider并添加了选择器,所以您应该这样修改清单:@AlexS您能提供一个示例吗?我只在清单中添加了文件提供程序
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;
}
}
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"));
}