I have been developing an app in Qt on Ubuntu which works with an SQLite database and several GB of files. Everything is working well in Ubuntu and Windows, but... when I try to port to Android I'm having some problems. I've placed the database.db file and other files on an SD card, installed it in my target device, and finally was able to "find" it with this code:
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." );
}
}
So, finally by using JNI to track down the SD card folder I'm getting the database to report that it is successfully opened. However, now when I try to read my first table I'm getting failure of the query.exec() in Android (that doesn't happen in 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; }
this returns:
D MyApp: ERROR: No query Unable to fetch row, SELECT time FROM history ORDER BY time DESC;
in Android, but works in other OSs. All subsequent attempts to read from the database also fail in Android. MyApp is a console app, I eventually want to run it as a service, but before taking that leap I'd like to see it work in "simple mode." The Application Output does throw a couple of warnings (marked W) before the program starts, but they don't seem connected?
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;
This is with latest stable Android Studio downloaded and configured yesterday, JDK 1.8, latest Qt Creator downloaded and installed yesterday running on Ubuntu 18.04, Qt 5.14.2, targeting an Android 8.0 phone. Sample Qt apps and simple GUI apps I have run on the phone successfully, and the http server side of the console app is working as expected. I've given the app READ and WRITE EXTERNAL STORAGE permissions (even though many notes suggest they are not needed for these versions...)
What else do I have to do for Android to get the SQLite database working?
open()won't return false even if the file doesn't exist; it will create a new empty database instead.