如何在所有设备上检索 sqlite 数据库文件?

How to retrieve sqlite database file on all devices?

我有一个应用程序可以获取 SQLite 数据库文件并通过电子邮件发送。问题是,在某些设备上我检索的文件路径 Context.getDatabasePath(“dbname.db”).getPath() returns 空。

我需要特定设备的任何特殊权限吗?或者是否有另一种方法可以检索适用于所有设备的数据库文件路径。

这是我用来获取并发送文件的代码:

public synchronized void sendDBMail(String subject, String body,
                                    String sender, String recipients, final DBSender.OnCompletionListener onCompletionListener) throws Throwable {

    // Create a default MimeMessage object.
    final Message message = new MimeMessage(session);

    // Set From: header field of the header.
    message.setFrom(new InternetAddress(sender));

    // Set To: header field of the header.
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));

    // Set Subject: header field
    message.setSubject(subject);

    // Create the message part
    BodyPart messageBodyPart = new MimeBodyPart();

    // Now set the actual message
    messageBodyPart.setText(body);

    // Create a multipar message
    Multipart multipart = new MimeMultipart();

    // Set text message part
    multipart.addBodyPart(messageBodyPart);

    // Part two is attachment
    messageBodyPart = new MimeBodyPart();
    File myDB = FileUtils.copyDBToSD(App.getContext(),BACKUP_DATABASES_DIR, DBHelper.DATABASE_NAME);
    String filePath = myDB.getPath();
    DataSource source = new FileDataSource(filePath);
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(DBHelper.DATABASE_NAME);
    multipart.addBodyPart(messageBodyPart);

    // Send the complete message parts
    message.setContent(multipart);

    // Send message
    Transport.send(message);
}

public static File copyDBToSD(Context ctx, String sdCardPath, String dataBaseFileName) throws Throwable {
    File dataBaseFile =  ctx.getDatabasePath(dataBaseFileName);
    File dataBaseCopy = FileUtils.createOrReadFileInSDCard(ctx,sdCardPath,dataBaseFileName);
    return copyFile(dataBaseFile, dataBaseCopy);
}

感谢您的帮助!

我在我的旧应用程序中使用了这个:

    private boolean expdb() {

            //exporting database file
            try {
                String filename = ("database_backup_" + DbOpenHelper.DB_NAME);
                File sdCard = Environment.getExternalStorageDirectory();
                File directory = new File(sdCard.getAbsolutePath() + "/yourAppName");
                //create directory if not exist
                if (!directory.isDirectory()) {
                    directory.mkdirs();
                }


                File data = Environment.getDataDirectory();

                if (directory.canWrite()) {
                    String currentDBPath = "//data//" + getActivity().getPackageName() + "//databases//" + DbOpenHelper.DB_NAME;

                    File currentDB = new File(data, currentDBPath);
                    File backupDB = new File(directory, filename);

                    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();
                    } else{
return false;}
                } else {
return false;}
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }

将您的 DBHelper 修改为:-

1) 包含一个 class 变量:-

    private static String DBPATH;

2) 在super调用add后的构造函数中(假设context是传入的Context的变量名,其他的相应修改):-

    DBPATH = context.getDatabasePath(DB_NAME).getPath();

3) 添加方法:-

    public static String getDBPath() {
        return DBPATH;
    }

4) 然后使用:-

    File dataBaseFile =  new File(DBhelper.getDBPath());

而不是

    File dataBaseFile =  ctx.getDatabasePath(dataBaseFileName);

然后您可以在 copyDBToSD 的签名中删除上下文。

这当然依赖于实例化的 DBhelper 实例。它还假设问题是基于 App.getContext() 是问题的原因。