This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/myddas/sqlite3/Android/www/index.wiki
Vitor Santos Costa d680fa0755 missing
2016-04-05 08:18:09 +01:00

216 lines
7.7 KiB
Plaintext

<h1>
SQLite Android Bindings
</h1>
<p> The SQLite library is a core part of the Android environment. Java
applications and content providers access SQLite using the interface in
the
<a href="http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html">android.database.sqlite</a> namespace.
<p> One disadvantage of using Android's built-in SQLite support is that the
application is forced to use the version of SQLite that the current version of
Android happened to ship with. If your application happens to require a newer
version of SQLite, or a build with a custom extension or
<a href=http://www.sqlite.org/vfs.html>VFS</a> installed, you're out of luck.
<p>The code in this project allows an application to use the
<a href=http://developer.android.com/tools/sdk/ndk/index.html>Android NDK</a>
to build a custom version of SQLite to be shipped with the application while
still continuing to use the standard Java interface.
<h2>Normal Usage</h2>
<h3>Installation</h3>
<p>
Android API levels 15 (Android 4.0.3) and greater are supported. If
targetting API level 16 or greater, use the default "trunk" branch of this
project. Or, for API level 15, use the "api-level-15" branch. It is not possible
to target an API level lower than 15.
<p>
Copy the following files from this project into the equivalent locations in
the application project.
<pre>
jni/Android.mk
jni/Application.mk
jni/sqlite/* (copy contents of directory recursively)
src/org/sqlite/database/* (copy contents of directory recursively)
</pre>
<p>
Following this, the directory structures should contain
[/tree?ci=trunk&re=%5ejni%7csrc/org/sqlite/data&expand | these files].
<p>
For API level 15 only, also copy the following:
<pre>
src/org/sqlite/os/* (copy contents of directory recursively)
</pre>
<p>
Directory "jni/sqlite/" contains copies of the sqlite3.h and sqlite3.c
source files. Between them, they contain the
<a href=http://www.sqlite.org/amalgamation.html>source code for the SQLite
library</a>. If necessary, replace these with the source for the specific
version of SQLite required. If SQLite is to be compiled with any special
pre-processor macros defined, add them to the "jni/sqlite/Android.mk" file
(not jni/Android.mk).
<p>
Once the files have been added to the project, run the command "ndk-build"
in the root directory of the project. This compiles the native code in
the jni/ directory (including the custom SQLite version) to shared libraries
that will be deployed to the device along with the application. Assuming
it is successful, unless you modify the sources or makefiles within the
jni/ directory structure, you should not need to run "ndk-build" again.
<h3>Application Programming</h3>
<p>
Before using any SQLite related methods or objects, the shared library
compiled using the ndk must be loaded into the application using the
following code:
<verbatim>
System.loadLibrary("sqliteX");
</verbatim>
<p>
One way to ensure that the shared library is loaded early enough is
to add it to a "static" block within the declaration of the application's
main Activity class.
<p>
The classes that make up the built-in Android SQLite interface reside in
the "android.database.sqlite" namespace. This interface provides all of
the same classes, except within the "org.sqlite.database.sqlite" namespace.
This means that to modify an application to use the custom version of
SQLite, all that is usually required is to replace all occurrences
"android.database.sqlite" within the source code with
"org.sqlite.database.sqlite". For example, the following:
<verbatim>
import android.database.sqlite.SQLiteDatabase;
</verbatim>
<p>should be replaced with:
<verbatim>
import org.sqlite.database.sqlite.SQLiteDatabase;
</verbatim>
<p>
As well as replacing all uses of the classes in the
android.database.sqlite.* namespace, the application must also be sure
to use the following two:
<verbatim>
org.sqlite.database.SQLException
org.sqlite.database.DatabaseErrorHandler
</verbatim>
<p>instead of:
<verbatim>
android.database.SQLException
android.database.DatabaseErrorHandler
</verbatim>
<p>Aside from namespace changes, there are other differences from the
stock Android interface that applications need to be aware of:
<ol>
<li> The SQLiteStatement.<a href="http://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html#simpleQueryForBlobFileDescriptor()">simpleQueryForBlobFileDescriptor()</a>
API is not available.
<li> The collation sequence "UNICODE" is not available.
<li> The collation sequence "LOCALIZED", which normally changes with the
system's current locale, is always equivalent to SQLite's built
in collation BINARY.
</ol>
<h2>Using The SQLite Encryption Extension</h2>
<p>
To use the <a href=http://www.sqlite.org/see/doc/trunk/www/readme.wiki>
SQLite Encryption Extension</a> (SEE) on Android, replace the sqlite3.c
file at "jni/sqlite/sqlite3.c" with a SEE-enabled version (i.e. the
concatenation of sqlite3.c and see.c - refer to the link above for
details). Next, open the file jni/sqlite/Android.mk and locate the
following two lines:
<verbatim>
# If using SEE, uncomment the following:
# LOCAL_CFLAGS += -DSQLITE_HAS_CODEC
</verbatim>
<p>
Uncomment the second of them, then run "ndk-build" as described above to
generate the shared libraries.
<p>
After opening or creating an encrypted database, the application must
immediately execute a PRAGMA to configure the encryption key. This must
be done before any other database methods are called. For example:
<verbatim>
import org.sqlite.database.sqlite.SQLiteDatabase;
...
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("my.db", null);
db.execSQL("PRAGMA key = 'secretkey'");
</verbatim>
<p>
Or, if you are using the
<a href=http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html>SQLiteOpenHelper</a>
helper class, the PRAGMA must be the first thing executed within the
onConfigure() callback. For example:
<verbatim>
import org.sqlite.database.sqlite.SQLiteDatabase;
import org.sqlite.database.sqlite.SQLiteHelper;
...
class MyHelper extends SQLiteOpenHelper {
...
void onConfigure(SQLiteDatabase db){
db.execSQL("PRAGMA key = 'secretkey'");
}
...
}
</verbatim>
<p>
Refer to the <a href=http://www.sqlite.org/see/doc/trunk/www/readme.wiki>
SEE documentation</a> for further details regarding encryption keys.
<p>Aside from supporting encrypted databases, SEE-enabled builds behave
differently in two more respects:
<ol>
<li> <p>The SQLiteDatabase.<a href="http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#enableWriteAheadLogging()">enableWriteAheadLogging()</a> method does not enable
connection pooling. It is not possible for connection pooling to be
used with a SEE-enabled build (even if the database is unencrypted).
<li> <p>In Android, if database corruption is encountered, or if an attempt is
made to open a file that is not an SQLite database, the default
behaviour is to delete the file and create an empty database file in
its place. In a SEE-enabled build, the default behaviour is to throw
an exception.<br><br>
The reason for this is that supplying an incorrect encryption key
is indistinguishable from opening a file that is not a database file.
And it seems too dangerous to simply delete the file in this case.
<br><br>
The default behaviour can be overriden using the
<a href="http://developer.android.com/reference/android/database/DatabaseErrorHandler.html">DatabaseErrorHandler</a> interface.
</ol>