駆け出しエンジニアぱかぱかの成長記録

引くほど忘れっぽい新卒2年目駆け出しSEぱかぱかの備忘録です。

【Android】見たい鳥をDBに保存する

こんにちは!日曜朝のぱかぱかです!

平日は残業、土日は遊びに費やしてしまいなかなか勉強時間が取れていない昨今…

随分前に作成した自作アプリでDBとの連携を行う機能の記事が書けていなかったのですが、ついに筆を進めております。

これを片付けて今日も午後から遊びに出かけてきます😇

 

それでは見ていきましょう!

 

「鳥図鑑」から「見たい鳥DB」に登録したい

まずは今回やりたいことをお話しします。

現在作っている野鳥コレクションアプリに存在する画面は以下の通りです。

 

鳥図鑑:鳥の情報が羅列されている

見たい鳥リスト:鳥図鑑から登録した見たい鳥のリストを表示

発見した鳥リスト:鳥図鑑から登録した発見した鳥のリストを表示

 

これを踏まえ今回のゴールは以下の2つになります。

★鳥図鑑で「見たい鳥へ登録」を押した際にその情報をDBに保存する

見たい鳥リストはDBから情報を取得して表示する

 

相変わらず味気ないトップ画面

 

DBとの連携

Androidの端末内にデータを保存するにはプリファレンスやストレージなどいくつか方法がありますが、今回はOS内にあらかじめ備わっているSQLiteデータベースを使っていきます!

私は以前OSS-DB SilverというPostgre SQL🐘の資格を取得していたので、ぜひDBとして実際に使う練習をしてみたいと思っていたのですが、デフォルトがSQLiteということなのでこれを使うほかありませんね…

今後アプリ開発をやっていくとしたら、ずっとSQLiteとお付き合いすることになるのでしょう。

正直違いはあまりよく分かりませんが!笑

 

DBを利用する手順としては以下のようになります。

データベースヘルパークラスを作成しインスタンスを生成する。

②アクティビティでデータベースヘルパーオブジェクトからデータベース接続オブジェクトSQLiteDatabaseオブジェクト)を取得する。

③SQLiteDatabaseオブジェクトを使ってSQLを実行、結果を取得する。

 

それでは1つずつ進めていきます。

 

データベースヘルパークラスを作成しインスタンスを生成

まずはSQLiteOpenHelperクラスを継承してDatabaseHelperというクラスを作成します。

SQLiteOpenHelperクラスではonCreate()onUpgrade()の2つが抽象メソッドとして定義されているため実装する必要があります。

onCreate()はコンストラクタで指定したDB名のDBが存在しない時、つまり初期状態に1回だけ実行されます。

よって、そのonCreateメソッド内に以下のようなデータベース作成用SQL文字列を記述することで初期設定を行います。

今回はwantBirdという見たい鳥の名前と登録日を登録するテーブルを作成します。

※今回onUpgrade()については一旦空の実装としているため省略します。

 

override fun onCreate(db: SQLiteDatabase) {
val sb = StringBuilder()
sb.append("CREATE TABLE wantBird (")
sb.append("_id INTEGER PRIMARY KEY,")
sb.append("name TEXT,")
sb.append("date TEXT")
sb.append(");")
val sql = sb.toString()

//SQLの実行。
db.execSQL(sql)
}

 

②アクティビティでSQLiteDatabaseオブジェクトを取得

次に鳥図鑑画面のActivityでヘルパーオブジェクトを生成、解放する処理を記述します。

 

・オブジェクトの生成

ヘルパーオブジェクトはアクティビティの様々な処理で使われるため、あらかじめアクティビティのプロパティとして生成しておく必要があります。

private val _helper = DatabaseHelper(this@BirdListActivity)

 

・オブジェクトの解放

実行タイミングはアクティビティの終了時、すなわちonDestroy()が最適です。

override fun onDestroy() {
// ヘルパーオブジェクトの解放。
_helper.close()
super.onDestroy()
}

 

次に生成したヘルパーオブジェクトからデータベース接続オブジェクトを取得し、データ保存処理を記述します。

ただ、現在は鳥図鑑のリストをタップした際に以下のようなダイアログを表示するようにしています。

よってデータ保存処理はダイアログフラグメントの「登録」ボタン処理中に記述してあげます。

 

 

③SQLiteDatabaseオブジェクトを使ってSQLを実行

「登録」ボタン押下時に実行されるinsertWantBirdメソッドの処理が以下です。

取得したデータベース接続オブジェクトを使ってインサート文を実行します。

これによって、鳥図鑑から見たい鳥リストに鳥を登録できるようになりました。

 

private fun insertWantBird(_birdId: Int, _birdName: String, _registerDate: String ) {
// データベースヘルパーオブジェクト。
val _helper = DatabaseHelper(requireContext())
// データベースヘルパーオブジェクトからデータベース接続オブジェクトを取得。
val db = _helper.writableDatabase

// インサート用SQL文字列の用意。
val sqlInsert = "INSERT INTO wantBird (_id, name, date) VALUES (?, ?, ?)"
//SQL文字列を元にプリペアドステートメントを取得。
var stmt = db.compileStatement(sqlInsert)
// 変数のバインド。
stmt.bindLong(1, _birdId.toLong())
stmt.bindString(2, _birdName)
stmt.bindString(3, _registerDate)
// インサートSQLの実行。
stmt.executeInsert()
}

 

次は見たい鳥リストの表示です。

見たい鳥リストのアクティビティでは以下のようにDBからデータを取得する処理を記述します。

 

val cursor = db.query("wantBird", null, null, null, null, null, null)
lvBirds.adapter = SimpleCursorAdapter(
this@WantBirdList,
R.layout.want_bird_row,
cursor,
arrayOf("name", "date"),
intArrayOf(R.id.tvBirdNameRow, R.id.tvRegisterDateRow),
0
)
db.close()

 

その結果がこちらです。

見たい鳥リストに登録した鳥が表示されるようになりました。

 

App Inspectionの機能を使って実際のDBの状態を見てみると以下のようになっています。

しっかりと登録されていますね。

 

今日はこれにて終了とします。

また少しずつアプリらしくなってきて嬉しいです。

ここまで読んでくださりありがとうございました。