QT on Android 调用数据库(SQLite)

QT打包Android的资源和打包windows资源的方式不同,像windows中的库,资源,只需要放到工程文件中并配置好正确的路径,就可以被读取到,但是打包成APK之后,资源的路径和windows是不一样的,甚至资源文件都没有被添加到APK中。

首先我们来看看APK的组成。APK本质上也是一个压缩文件,因此也是包含文件路径的。

这里我们拿一个已经生成好的debug APK作为例子看看QT发布的APK包含哪些文件,如下图

QT on Android 调用数据库(SQLite)

 

 

 可以看到APK内部还是由一系列文件夹构成的,而我们所需要的资源,最终也应该被添加到这些文件夹中(assets文件夹),这样才能在Android程序运行时找到正确的资源路径。

在工程目录android-build文件夹中,也存在一个assets文件夹

QT on Android 调用数据库(SQLite)

 

 但是我们直接将数据库赋值到这个文件夹中,最后打包出来的APK依然是没有包含数据的

因为android-build文件夹是每一次构建时都要重新生成的,也就是说,这些文件是根据我们代码中的配置信息生成,如果代码中没有添加相关的资源信息,那么打包出来的APK依然不会将资源添加进去。

所以需要先修改.pro文件,让系统能自动将我们需要的资源添加到assets文件夹中。

 

首先,在.pro文件的同级文件夹中新建文件夹database

QT on Android 调用数据库(SQLite)

 

 然后将我们需要的数据库文件添加到database文件夹中

QT on Android 调用数据库(SQLite)

 

 

然后需要在.pro文件中添加如下语句

android{
    data.files += database/Subjects.db
    data.path = /assets/database
    INSTALLS += data
}

data.files += 源代码路径下的数据库文件路径
data.path = 编译后存放的文件路径(assets文件夹下的文件,会自动打包到apk)
INSTALLS += 使用INSTALLS将文件复制到输出目录

 

 之后,在点击构建按钮,将会生成一个APK,我们点进这个apk

QT on Android 调用数据库(SQLite)

 

 就可以看到我们需要用的数据已经被添加到这个APK里面了。

最后就是怎么访问数据库了

原理和在windows中访问数据相同,都是需要配置正确的文件路径,其他的就基本上相同了

    QSqlDatabase database;
    if(QSqlDatabase::contains("qt_sql_default_connection"))
      database = QSqlDatabase::database("qt_sql_default_connection");
    else
      database = QSqlDatabase::addDatabase("QSQLITE");

#ifdef Q_OS_WIN
    database.setDatabaseName(QApplication::applicationDirPath()+"/"+dbName);
#endif

#ifdef Q_OS_ANDROID
    QFile file("assets:/database/Subjects.db");
    if(file.exists())
    {
        file.copy("./Subjects.db");
        file.setPermissions(QFile::ReadOwner|QFile::WriteOwner);
        database.setDatabaseName("Subjects.db");
    }
#endif

    if (!database.open())
    {
        qDebug() << "Error: Failed to connect database." << database.lastError();
        return;
    }

在语句QFile file("assets:/database/Subjects.db");这个文件路径正好就是我们在APK压缩报截图中,数据库的文件路径,读取到数据库之后,将其拷贝到安卓本地文件系统中读写。

app第一次安装的时候是没有的,所以db不存在,所以会进入if中执行语句,如果你安装好app后,再次打开这个app,系统同样会执行到这里,就不会 进入if中,所以这句话很重要,就是为了 避免每次打开程序,都把app安装包内带有的db文件覆盖到指定地址上。

设置完读写权限之后就可以通过setDatabaseName函数调用数据库了。

除了数据库,其他的资源文件比如图片,字体等等都可以用这样的方式添加到APK中。

上一篇:FastReport打印SQLite数据库在一页上


下一篇:TSINGSEE青犀视频编译行人识别系统写入sql(python)语句实现流程