发送sqlite数据库Android / Java时无法附加文件

时间:2018-07-04 21:56:09

标签: java android sqlite android-studio android-intent

我是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();
                }
            }

0 个答案:

没有答案