Asset/data size limit on android using SQLiteAssetHelper? - android

Everything was working fine before I added some "big" tables to my file.
I have a table that weights about 2Mo, and now I am getting this error :
07-19 00:47:51.210 4703-4703/com.lectem.gecharacters
W/SQLiteAssetHelper﹕ copying database from assets... 07-19
00:47:51.280 4703-4705/com.lectem.gecharacters E/Database﹕ close()
was never explicitly called on database
'/data/data/com.lectem.gecharacters/databases/gechar2.sqlite'
android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was
opened here
at android.database.sqlite.SQLiteDatabase.(SQLiteDatabase.java:1810)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.returnDatabase(SQLiteAssetHelper.java:408)
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.createOrOpenDatabase(SQLiteAssetHelper.java:386)
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getWritableDatabase(SQLiteAssetHelper.java:182)
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getReadableDatabase(SQLiteAssetHelper.java:254)
I tried to empty the table, and it works again after this...
I am using the SQLite Manager plugin for Firefox, and the SQLiteAssetHelper library.
Can't open database with SQLiteAssetHelper didn't help.
EDIT: I forgot to mention that it works fine on my phone (android 4.1) but the error occurs on my Tablet (android 2.2.1)

The answer was in the readme... https://github.com/jgilfelt/android-sqlite-asset-helper
I was compressing my database using gzip, but it seems you really need to use zip for old devices.
Earlier versions of this library required the database asset to be
compressed within a ZIP archive. This is no longer a requirement, but
is still supported. Applications still targeting Gingerbread (API 10)
or lower should continue to provide a compressed archive to ensure
large database files are not corrupted during the packaging process.
The more Linux friendly GZIP format is also supported. The naming
conventions using the above example are as follows:
ZIP: assets/databases/northwind.db.zip (a single SQLite database file must be the only file within the archive)
GZIP: assets/databases/northwind.db.gz

Related

Room Database migration crash

I have an DB migration:
val MIGRATION_8_9 = object : Migration(8, 9) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE RideEntity RENAME frontVideoPresent TO frontVideoState")
database.execSQL("ALTER TABLE RideEntity RENAME rearVideoPresent TO rearVideoState")
}
}
When testing this migration on local Samsung phones it worked fine. The in production with help of craslytics I seen this crash:
Fatal Exception: java.lang.RuntimeException
Exception while computing database live data.
Caused by android.database.sqlite.SQLiteException
near "frontVideoPresent": syntax error (Sqlite code 1 SQLITE_ERROR): , while
compiling: ALTER TABLE RideEntity RENAME frontVideoPresent TO frontVideoState, (OS
error - 11:Try again)
This is happened on Huawei Mate 20 phone. How to understand better this crash? This is OS related?
I can not remove the rename now, because many users that updated the app the column renaming worked, but users with Huawei phones may suffer this crash.
I am open to your suggestions...
Looks like version of sqlite on some devices doesn't support column renaming because android app use build-in version on sqlite library to android OS. That's why version of sqlite depends on android's api level version (where app running). According to sqlite release notes (paragraph 2) the support for renaming columns was added in version 3.25.0 and according to google docs (and other answer on stackoverflow)the column's renaming on android supports since android api level 30.
To solve the problem of fragmentation of slqlite library you can use android-requery which allows to use last version of sqlile in all android versions(since API level 14). It's easy to use this library with room.

QT QuaZip open() fail -1000

I am trying to uncompress a Zip file. Using the latest Qt 5.15 on an Android device.
QFile downloadedZipFile(VALID_ZIP_LOCATION);
QuaZip zip(&downloadedZipFile);
if (!zip.open(QuaZip::mdUnzip)) {
qDebug() << "error" << zip.getZipError();
}
If my file is above 2GB it am getting an error -1000.
Files below 2GB are working as expected.
I tried
zip.setZip64Enabled(true);
before opening the file without success.
I also tried to use the constructor
QuaZip zip(VALID_ZIP_LOCATION)
Upon accessing the zip later I also get the following error:
QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode
which makes sense, as it couldn't open the file in the first place.
Any help is appreciated, as I am struggling with this Problem for a few days already.
The problem is an unresolved QT-Bug. Where QFile::seek cannot exceed a limit above a 32Bit Integer.
https://bugreports.qt.io/browse/QTBUG-84033
After identifying the problem I could resolve this issue by implementing native code for unzipping files in java for android.
Since iPhones are only running on 64Bit systems the native implementation did not need to be ported to ObjC.

Any library to read mdict *.MDX files in android?

I have a .mdx file that infact is a dictionary database (some android apps like bluedict can read its data).
I have used Daemon.tools but it could not open it.
I was looking for any library or sources which helps me to read MDX dictionary files in Java, I have found some resources already such as KnIfER/mdict-java but it does not work in Android Studio (it has errors on accumulation_blockId_tree.xxing(new myCpr(position,1)).getKey().value line and it is connot resolve symbol 'value'). Does any one knows a good source about these files and possible libraries which could be used for it?.
Well, actually this is my java project.
the error mentioned is just a problem of jdk version. you can add <> parentheses after myCpr and convert return of xxing to type myCpr<Integer,Integer> .
But now, I have very much reduced usage of rbtree and use more binary list searching.have a look there.

Unable to update database in android using SQLiteAssetHelper

I'm using SQLiteAssetHelper. I tried to upgrade the database by adding few insertions into the testdb.db file then according to instructions on
https://github.com/jgilfelt/android-sqlite-asset-helper
I renamed this new file to testdb.db_upgrade_1-2.sql and added to the asset folder in the android app. I changed the database version to 2 in the Databasehandler, but still there is an error as shown in the stacktrace which is as follows
I/SQLiteAssetHelper: successfully opened database testdb.db
W/SQLiteAssetHelper: Upgrading database testdb.db from version 1 to 2...
W/SQLiteAssetHelper: processing upgrade: databases/testdb.db_upgrade_1-2.sql
E/SQLiteLog: (1) near "SQLite": syntax error
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
After this the app crashes.
My asset folder contains both /databases/testdb.db
and /databases/testdb.db_upgrade_1-2.sql
I'm using sqlite3 on my computer to generate the database file
I renamed this new file to testdb.db_upgrade_1-2.sql
That is incorrect. testdb.db_upgrade_1-2.sql is supposed to be a text file containing SQL statements to apply to your schema v1 database to convert it into a schema v2 database.
Quoting the documentation, with emphasis added:
Update the initial SQLite database in the project's assets/databases directory with the changes and create a text file containing all required SQL commands to upgrade the database from its previous version to it's current version and place it in the same folder.

ServiceLoader.load is not finding the META-INF/services

So I want to build an extensible android application where developers can add 'CustomDevice' classes and the main program will run them automatically without editing existing code.
I've read about Service Provider interface and thought that would be a nice way to go about it.
So I tested it and created an interface called 'ICustomDevice' which custom device classes are expected to implement.
I've created a class called 'DummyDevice' that implements ICustomDevice.
Both DummyDevice and ICustomDevice are in the same package "CustomDevicePackage".
So in my main program I run the following.
ServiceLoader<ICustomDevice> loader = ServiceLoader.load(ICustomDevice.class);
Iterator<ICustomDevice> devices = loader.iterator();
System.out.println("Does it have devices? " + devices.hasNext());
It always returns false, which means it's not finding the 'DummyDevice'
In my eclipse project I created a folder at 'src' called META-INF and under it, a subfolder called 'services'.
'Services' has a file named 'CustomDevicePackage.ICustomDevice' with a line of content 'CustomDevicePackage.DummyDevice'.
Am I doing it right? Every example I see about SPI is about loading JARS.
I'm not loading a JAR, I'm trying to run a class in the same Project. Does this method only works for loading JARs? I want my program to support loading local subclasses and external JARs alike.
I am adding this as an answer but leaving the prior "answer" to provide extended code detail for this workaround. I am working on reporting the prior answer results as a bug to Google.
Because the Android implementation of java.util.ServiceLoader is broken (always populating internal java.security.AccessControlContext field with AccessController.getContext() even if System.getSecurityManager() == null), the workaround is to create your own ServiceLoader class by copying the code found at OpenJDK for Java 8 into your class, add specific imports required from java.util without using import java.util.*;, and call that ServiceLoader in your code (you will have to fully reference the ServiceLoader you created to over ambiguity).
This isn't elegant but it is a functional workaround that works! Also, you will need to use a ClassLoader in your ServiceLoader.load() call. That ClassLoader will either have to be YourClass.class.getClassLoader() or a child ClassLoader of the class' ClassLoader.
Though it's an old post, This may be still be of some help to others:
When I was running or debugging a project that contained a ServiceLoader Class, I had to put the META-INF/services folder into the src/ folder in Eclipse.
If I tried to export the project as Runnable jar and tried to use the class with the service loader, it never worked.
When I checked the jar, unzipping it, I found the folder under src/META-INF/services though.
Only when I also added the META-INF folder directly in the root directory of the jar, it started to work.
I haven't found a fix though inside Eclipse, that makes sure it gets exported right...maybe an ANT script can solve this issue, but so far no attempts made...
This is an answer:
At some point, Android removed the AccessControlContext field in ServiceLoader and ServiceLoader now works. As my comments indicate, this was reproduceable using the "out-of-the-box" OREO (API 26) Intel Atom x86 emulator with Android Studio (also fresh download). 24 hours later, ServiceLoader no longer contained the acc field (as shown in the Android Studio debugger with the same emulator). The Android SDKs dating back to API 24 do not show the acc field.
Per the Android developer currently maintaining the ServiceLoader code:
He is not aware of ServiceLoader ever having the acc field in Android (it did as we were able to reproduce) and thought the debugger/emulator might have been using JDK code (but I showed the OpenJDK code works correctly). Somewhere along the way, the errant code was updated and I am no longer able to reproduce.
Be sure your OS is up-to-date and you should no longer see this phenomena.

Categories

Resources