Why and Where to call setLocale

2019-05-24 22:03发布

问题:

I need to create a SQLite DB for my application. I'll need to store text in several European languages, so there will be plenty of accented characters and other weird marks. I'm extending SQLiteOpenHelper.

Inspecting the .db file I noticed there's an extra table named android_metadata. There's a single column named locale, which is set to "en_US" by default in my simulator.

I've readed the SQLite section in the developer guide, and also the javadocs for SQLiteOpenHelper and SQLiteDatabase, searched in SO and in Google, but nowhere I could find what is the correct place to set the locale to the DB, or if it is really neccesary. Guessing it should be done at DB creation, I tried calling db.setLocale in the helper's onCreate method, but I'm, getting this exception:

BEGIN TRANSACTION failed setting locale
FATAL EXCEPTION: Thread-9
android.database.sqlite.SQLiteException: cannot start a transaction within a transaction
at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1950)

This is how my method looks:

public class MyOpenHelper extends SQLiteOpenHelper {

    @Override
    public void onCreate(SQLiteDatabase db) {   
        db.setLocale(new Locale("en","EN"));
        ...
    }

    ...
}

And here are my questions:

  1. Do I really need to set the locale to the DB? I don't really need to get the queries sorted out of the box, as I can always sort the results myself later.
  2. Where should I call setLocale?

回答1:

  1. You'll need to set the locale only if you intend to use the LOCALIZED collation algorithm, which depends on the system locale,
  2. As mentioned in your answer, call setLocale() on onConfigure().


回答2:

Ok, I've found in the SQLiteOpenHelper docs the following method:

void onConfigure(SQLiteDatabase db)

Copied from the method description:

Called when the database connection is being configured, to enable features such as write-ahead logging or foreign key support. This method is called before onCreate(SQLiteDatabase), onUpgrade(SQLiteDatabase, int, int), onDowngrade(SQLiteDatabase, int, int), or onOpen(SQLiteDatabase) are called. It should not modify the database except to configure the database connection as required. This method should only call methods that configure the parameters of the database connection, such as enableWriteAheadLogging() setForeignKeyConstraintsEnabled(boolean), setLocale(Locale), setMaximumSize(long), or executing PRAGMA statements.

This method gets called when the helper is creating the DB for the first time. I've checked the db file and the android_metadata now contains the correct locale. I've run some tests to store accented chars and they are written correctly to the db even without setting the proper locale.