Reputation: 877
I am attempting to create a local SQLite database with SQLCipher
Here is my method for creating/writing to the database:
class DatabaseUtils {
val storagePath = Environment.getExternalStorageDirectory()
fun storeTransaction(context: Context, password: String, transaction: Transaction) {
SQLiteDatabase.loadLibs(context)
val databaseFile: File = context.getDatabasePath("$storagePath/Test.db")
if (!databaseFile.exists()) {
databaseFile.mkdirs()
}
val database: SQLiteDatabase = SQLiteDatabase.openOrCreateDatabase(databaseFile, password, null)
database.execSQL("CREATE TABLE IF NOT EXISTS Transactions(cardNumber INTEGER)")
database.execSQL("INSERT INTO Transactions(cardNumber) VALUES(${transaction.cardNumber})")
database.close()
}
}
I have declared
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
and
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in my manifest, and requested permission when I called the function like so:
override fun onStart() {
super.onStart()
initUI()
if (ContextCompat.checkSelfPermission(context!!, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity!!,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
1)
}
if (ContextCompat.checkSelfPermission(context!!, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity!!,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
2)
}
val databaseUtils = DatabaseUtils()
databaseUtils.storeTransaction(context!!,getString(R.string.app_version), Transaction("12345678"))
}
The directory gets created, but I am still getting the above error when I call openOrCreateDatabase. What am I missing?
Upvotes: 1
Views: 1526
Reputation: 1006914
Problem #1: SQLiteDatabase
needs a file, but you made it a directory:
if (!databaseFile.exists()) {
databaseFile.mkdirs()
}
Delete those three lines, and delete the directory on your device. Or, do not pass databaseFile
to SQLiteDatabase.openOrCreateDatabase()
, but instead pass a File
object pointing to a file inside of your directory.
Problem #2: You are trying to write to external storage, yet you do not hold the permissions. ActivityCompat.requestPermissions()
is not a blocking call. When it returns, you do not yet hold the permissions. Yet, in your code, you are rolling right along attempting to use the permissions that you do not yet hold.
Beyond that:
Do not use string concatenation to assemble SQL statements, as you are in the second execSQL()
call. Use ?
as a placeholder and pass your arguments as the second parameter to execSQL()
. This is especially important for strings, as SQLCipher+SQLite will properly escape special characters and stuff for you.
You are doing disk I/O on the main application thread, which will cause your app's UI to freeze while that I/O is occurring.
Upvotes: 2