【发布时间】:2020-04-20 03:11:48
【问题描述】:
我一直在 Ubuntu 上使用 Qt 开发一个应用程序,它可以与 SQLite 数据库和几 GB 的文件一起使用。在 Ubuntu 和 Windows 中一切都运行良好,但是......当我尝试移植到 Android 时,我遇到了一些问题。我已将 database.db 文件和其他文件放在 SD 卡上,将其安装在我的目标设备中,最后能够使用以下代码“找到”它:
QString dbName;
#ifdef Q_OS_ANDROID
QAndroidJniObject androidContext = QtAndroid::androidContext();
QAndroidJniObject dir = QAndroidJniObject::fromString(QString(""));
QAndroidJniObject path = androidContext.callObjectMethod("getExternalFilesDir",
"(Ljava/lang/String;)Ljava/io/File;",
dir.object());
// qInfo() << "Path: " + path.toString();
dbName = path.toString()+"/database.db";
#else
QSettings *sp = new QSettings();
dbName = sp->value( "dbName", "/database.db" ).toString();
sp->deleteLater();
#endif
qDebug( "Database::Database(%s)", qPrintable( dbName ) );
const QString DRIVER("QSQLITE");
if ( !QSqlDatabase::isDriverAvailable(DRIVER) )
{ qDebug( "QSqlDatabase::isDriverAvailable(%s) is false", qPrintable(DRIVER) ); }
else
{ db = QSqlDatabase::addDatabase(DRIVER);
db.setDatabaseName( dbName );
QSqlDriver *driver = QSqlDatabase::database().driver();
if ( !db.open() )
{ qDebug( "Error opening database %s: %s", qPrintable( dbName ), qPrintable( db.lastError().text() ) );
}
else
{ qDebug( "Database opened." );
}
}
所以,最后通过使用 JNI 来追踪 SD 卡文件夹,我让数据库报告它已成功打开。但是,现在当我尝试读取我的第一个表时,我在 Android 中遇到 query.exec() 失败(这在 Linux/Windows 中不会发生):
QSqlQuery query(db);
query.prepare( "SELECT time FROM history ORDER BY time DESC;" );
if ( !query.exec() ) { qDebug( "ERROR: %s, %s", qPrintable( query.lastError().text() ), qPrintable( query.executedQuery() ) ); return; }
返回:
D MyApp: ERROR: No query Unable to fetch row, SELECT time FROM history ORDER BY time DESC;
适用于 Android,但适用于其他操作系统。所有后续从数据库读取的尝试在 Android 中也会失败。 MyApp 是一个控制台应用程序,我最终希望将它作为服务运行,但在实现这一飞跃之前,我希望看到它以“简单模式”运行。应用程序输出确实在程序启动之前抛出了几个警告(标记为 W),但它们似乎没有连接?
I zygote : Late-enabling -Xcheck:jni
W System : ClassLoader referenced unknown path:
I Qt : qt started
I zygote : Do partial code cache collection, code=26KB, data=23KB
I zygote : After code cache collection, code=26KB, data=23KB
I zygote : Increasing code cache capacity to 128KB
I zygote : Do partial code cache collection, code=62KB, data=55KB
I zygote : After code cache collection, code=62KB, data=55KB
I zygote : Increasing code cache capacity to 256KB
D OpenGLRenderer: HWUI GL Pipeline
I Adreno : QUALCOMM build : 94aeef9, Ie8d0be8cd4
I Adreno : Build Date : 11/09/17
I Adreno : OpenGL ES Shader Compiler Version: EV031.22.00.01
I Adreno : Local Branch :
I Adreno : Remote Branch :
I Adreno : Remote Branch :
I Adreno : Reconstruct Branch :
W RenderThread: type=1400 audit(0.0:2413): avc: denied { search } for name="proc" dev="debugfs" ino=12448 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:qti_debugfs:s0 tclass=dir permissive=0
I Adreno : PFP: 0x005ff087, ME: 0x005ff063
I OpenGLRenderer: Initialized EGL, version 1.4
D OpenGLRenderer: Swap behavior 2
I zygote : Do full code cache collection, code=112KB, data=112KB
I zygote : After code cache collection, code=110KB, data=100KB
D MyApp: Database::Database(/storage/emulated/0/Android/data/com.mangocats.myapp/files/database.db)
D MyApp: Database opened.
D MyApp: ERROR: No query Unable to fetch row, SELECT time FROM history ORDER BY time DESC;
这是昨天下载和配置的最新稳定 Android Studio,JDK 1.8,昨天下载和安装的最新 Qt Creator,在 Ubuntu 18.04,Qt 5.14.2 上运行,针对 Android 8.0 手机。我在手机上成功运行的示例 Qt 应用程序和简单的 GUI 应用程序,并且控制台应用程序的 http 服务器端按预期工作。我已授予应用 READ 和 WRITE EXTERNAL STORAGE 权限(尽管许多注释表明这些版本不需要它们......)
我还需要为 Android 做什么才能让 SQLite 数据库正常工作?
【问题讨论】:
-
检查数据库文件路径是否正确。
open()即使文件不存在也不会返回 false;它将创建一个新的空数据库。 -
好消息,我敢打赌就是这样。