我是Android和Java的新手。我的应用程序具有一个菜单图标,单击该菜单图标后应在其中复制产品数据库(应用程序是库存管理器)并将其作为电子邮件附件发送,但是当电子邮件应用程序打开时,我看到“无法附加文件”并且没有附件
我的猜测是我放置的MIME类型存在问题,或者我拥有的代码实际上没有按照我的预期去做。
代码:
// this method copies the database to external storage so that it can later be sent as an attachment
public void copyDatabaseAndEmailIt() {
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite())
{
String currentDBPath = "\\data\\com.example.lordi.restaurantcastlesuppliesmanager\\databases\\products.db";
String backupDBPath = "products.db";
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
//if database found in the app copy and show toast
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(CatalogActivity.this, "Backup Complete", Toast.LENGTH_SHORT).show();
}
}
}
catch (Exception e) {
Log.w("Settings Backup", e);
}
// to escape error because of URI exposure I invoke this lame method, other one with FileProvider a little bit too complex
if(Build.VERSION.SDK_INT>=24){
try{
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
}catch(Exception e){
e.printStackTrace(); }
}
String filename = "products.db";
File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
Uri path = Uri.fromFile(filelocation);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("application/x-sqlite3");
// the attachment
emailIntent.putExtra(Intent.EXTRA_STREAM, path);
// the mail subject
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(emailIntent); }
修改后的代码(仍然无效):
else if (mode.equals(emailAllData)) {
//copyDatabaseAndEmailIt();
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
Log.d("Test", "sdcard mounted and writable");
String currentDBPath = "\\data\\com.example.lordi.restaurantcastlesuppliesmanager\\databases\\products.db";
String backupDBPath = "products.db";
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
//if database found in the app copy and show toast
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(CatalogActivity.this, "Backup Complete", Toast.LENGTH_SHORT).show();
//String filename = "products.db";
File filelocation = new File(backupDB, Environment.getExternalStorageDirectory().getAbsolutePath());
Uri path = Uri.fromFile(filelocation);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("*/*");
// the attachment
emailIntent.putExtra(Intent.EXTRA_STREAM, path);
// the mail subject
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(emailIntent);
}
}
else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
Log.d("Test", "sdcard mounted readonly");
}
else {
Log.d("Test", "sdcard state: " + state); }
}
catch (Exception e) {
Log.w("Settings Backup", e);
}
//to escape error because of URI exposure I invoke this lame method, other one with FileProvider a little bit too complex
if(Build.VERSION.SDK_INT>=24){
try{
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
}catch(Exception e){
e.printStackTrace(); }
}
尝试检查问题是否出在SD卡上,不是问题,从日志中读取-已安装且可写。编辑的代码,但是甚至无法打开电子邮件活动。
使用断点和日志我得到了:
W/Settings Backup: java.io.FileNotFoundException: /data/com.example.lordi.restaurantcastlesuppliesmanager\databases\products.db (No such file or directory)
已编辑代码#2(无文件例外):
else if (mode.equals(emailAllData)) {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
FileChannel source= null;
FileChannel destination = null;
String currentDBPath = "/data/"+ getPackageName() +"/databases/"+ ProductDbHelper.Db_NAME;
String retrievedDBPAth = getDatabasePath(ProductDbHelper.Db_NAME).getPath();
String backupDBPath = "/storage/extSdCard/mydatabase";
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
File retrievedDB = new File(retrievedDBPAth);
Log.d("PATHS", " CurrentDB=" +
currentDBPath + "\n\t" + currentDB.getPath() +
"\n\tExists=" + String.valueOf(currentDB.exists()) +
"\nBackup=" + backupDBPath + "\n\t" + backupDB.getPath() +
"\n\tExists=" + String.valueOf(backupDB.exists()) +
"\nRetrieved DB=" + retrievedDBPAth + "\n\t" + retrievedDB.getPath() +
"\n\tExists=" + String.valueOf(retrievedDB.exists())
);
try {
source = new FileInputStream(currentDB).getChannel();
destination = new FileOutputStream(backupDB).getChannel();
//destination.transferFrom(source, 0, source.size());
source.close();
destination.close();
} catch(IOException e) {
e.printStackTrace();
Toast.makeText(this, "Err:"+e, Toast.LENGTH_LONG).show();
}
}