#目的
Kotlinでデータベース接続をし、画像の追加、削除までを実装する。
#環境
Android Studio 3.5.2
Build #AI-191.8026.42.35.5977832, built on October 31, 2019
JRE: 1.8.0_202-release-1483-b03 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
##KotlinでのDB接続の手順
適当なクラス名でKotlinファイルを作成します。
###まずは定義を記述
//テーブル定義
object PhotoTable : BaseColumns {
const val TABLE_NAME = "photo"
const val COLUMN_NAME_BITMAP = "bitmap"
}
//テーブル作成のSQL
private const val SQL_CREATE_PHOTO = "CREATE TABLE ${PhotoTable.TABLE_NAME}" +
" (${BaseColumns._ID} INTEGER PRIMARY KEY," +
" ${PhotoTable.COLUMN_NAME_BITMAP} BLOB NOT NULL)"
//テーブル削除のSQL
private const val SQL_DELETE_PHOTO = "DROP TABLE IF EXISTS ${PhotoTable.TABLE_NAME}"
private const val DATABASE_VERSION = 1
private const val DATABASE_NAME = "Practice.db"
画像はバイナリーデータとして保存するので型はBLOBになります。
###SQLiteOpenHelperクラスを継承
class DbHelper(context: Context): SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(SQL_CREATE_PHOTO)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL(SQL_DELETE_PHOTO)
onCreate(db)
}
}
今回は最低限オーバーライドする必要があるCreateとUpgradeのみです。
##UI
- 画像表示用ImageView(id:imageView)
- 画像追加ボタン(id:addPhotoButton)
- 画像削除ボタン(id:deletePhotoButton)
##レコ―ドの追加
###画像追加ボタンのクリック処理
addPhotoButton.setOnClickListener{
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"
startActivityForResult(Intent.createChooser(intent,"写真を選択"),CHOOSE_PHOTO)
}
画像を選択するActivityを起動します。
###画像選択後の処理
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == CHOOSE_PHOTO
&& resultCode == Activity.RESULT_OK
&& data != null){
//選択した画像のUriからBitmapを取得
val bitmap = getBitmapFromUri(data.data)
bitmap?:return
//画像表示用のImageViewに表示させときます
imageView.setImageBitmap(bitmap)
//Bitmapをバイナリーに変換してDBに登録します
val values = getContentValues(getBinaryFromBitmap(bitmap))
val db = dbHelper.writableDatabase
photoId = db.insert(PhotoTable.TABLE_NAME, null, values) //レコード追加
db.close()
Toast.makeText(this,"登録しました",Toast.LENGTH_LONG).show()
}
}
//Bitmapを取得
//@param 画像Uri
//@return Bitmap
private fun getBitmapFromUri(uri: Uri?): Bitmap? {
uri?:return null
val parcelFileDescriptor: ParcelFileDescriptor? =
this.contentResolver.openFileDescriptor(uri, "r")
parcelFileDescriptor?:return null
val fileDescriptor: FileDescriptor = parcelFileDescriptor.fileDescriptor
val image: Bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor)
parcelFileDescriptor.close()
return image
}
//Binaryを取得
//@param Bitmap
//@return Binary
private fun getBinaryFromBitmap(bitmap:Bitmap):ByteArray{
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
return byteArrayOutputStream.toByteArray()
}
//値セットを取得
//@param URI
//@return 値セット
private fun getContentValues(binary:ByteArray): ContentValues {
return ContentValues().apply {
put("${PhotoTable.COLUMN_NAME_BITMAP}",binary)
}
}
レコードの追加は以上です。
##レコードの削除
###画像削除ボタンのクリック処理
deletePhotoButton.setOnClickListener{
val db = dbHelper.writableDatabase
db.delete(PhotoTable.TABLE_NAME,"_ID = $photoId",null) //レコード削除
db.close()
//画像表示用ImageViewを元のに戻してます
imageView.setImageResource(R.drawable.art)
Toast.makeText(this,"削除しました",Toast.LENGTH_LONG).show()
}
レコードの削除は以上です。
#まとめ
- SQLiteOpenHelperを理解する
https://developer.android.com/reference/kotlin/android/database/sqlite/SQLiteOpenHelper - 画像をバイナリーに変換する
ちなみに、バイナリーをBitmapに変換する際は
val binary = //DBから取得したBinary
val bitmap = BitmapFactory.decodeByteArray(binary,0,binary.size)
で、取得できます。
##参考にしたサイトとソースコード
参考サイト
https://developer.android.com/training/data-storage/sqlite?hl=ja
ソースコード
https://github.com/date62noka3/database-kotlin
#最後に
補足という形で新たに記事を投稿しました。
合わせてお読みください。
https://qiita.com/date62noka3/items/573dbf84b41013ed9812