前提・実現したいこと
Androidでデータ保存を行う方法を勉強しています。データベースはSQLiteを使います。
アプリを作成したところ、ListViewで表示されてるメニューリストをタップしたらアプリが落ちてしまいますが、原因が分かりません。
教科書通りにコードを書いたつもりで、何度も確認したのですが、間違ってるところが見当たりませんでした。
教科書 Androidアプリ開発の教科書 なんちゃって開発者にならないための実践ハンズオン
発生している問題・エラーメッセージ
MainActivity.kt: (36, 27): Parameter 'view' is never used
該当のソースコード
kotlin
1package com.example.databasesample 2 3import androidx.appcompat.app.AppCompatActivity 4import android.os.Bundle 5import android.view.View 6import android.widget.* 7import kotlinx.android.synthetic.main.activity_main.* 8 9class MainActivity : AppCompatActivity() { 10 11 //選択されたカクテルの主キーIDを表すフィールド 12 private var _cocktailId = -1 13 //選択されたカクテル名を表すフィールド 14 private var _cocktailName = "" 15 16 //データベースヘルパーオブジェクト 17 private val _helper = DatabaseHelper(this@MainActivity) 18 19 override fun onCreate(savedInstanceState: Bundle?) { 20 super.onCreate(savedInstanceState) 21 setContentView(R.layout.activity_main) 22 23 //カクテルリスト用ListView(lvCoctail)を取得 24 val lvCocktail = findViewById<ListView>(R.id.lvCocktail) 25 //lvCocktailにリスナを登録 26 lvCocktail.onItemClickListener = ListItemClickListener() 27 } 28 29 override fun onDestroy() { 30 //ヘルパーオブジェクトの開放 31 _helper.close() 32 super.onDestroy() 33 } 34 35 //保存ボタンがタップされた時の処理メソッド 36 fun onSaveButtonClick(view: View) { 37 //感想欄を取得 38 val etNote = findViewById<EditText>(R.id.etNote) 39 //入力された感想を取得 40 val note = etNote.text.toString() 41 42 //データベースヘルパーオブジェクトからデータベース接続オブジェクトを取得 43 val db = _helper.writableDatabase 44 45 //まず、リストで選択されたカクテルのメモデータをを削除。その後インサートを行う。 46 //削除用SQL文字列を用意 47 val sqlDelete = "DELETE FROM cocktailmemos WHERE _id = ?" 48 //SQL文字列を元にプリペアドステートメントを取得 49 var stmt = db.compileStatement(sqlDelete) 50 //変数のバイト 51 stmt.bindLong(1, _cocktailId.toLong()) 52 //削除SQLの実行 53 stmt.executeUpdateDelete() 54 55 //インサート用SQL文字列の用意 56 val sqlInsert = "INSERT INTO cocktailmemos (_id, name, note) VALUES (?, ?, ?)" 57 //SQL文字列を元にプリペアドステートメントを取得 58 stmt = db.compileStatement(sqlInsert) 59 //変数のバイド 60 stmt.bindLong(1, _cocktailId.toLong()) 61 stmt.bindString(2, _cocktailName) 62 stmt.bindString(3, note) 63 //インサートSQLの実行 64 stmt.executeInsert() 65 66 //感想欄の入力値を消去 67 etNote.setText("") 68 //カクテル名表示するTextViewを取得 69 val tvCocktailName = findViewById<TextView>(R.id.tvCocktailName) 70 //カクテル名を「未選択」に変更 71 tvCocktailName.text = getString(R.string.tv_name) 72 //保存ボタンを取得 73 val btnSave = findViewById<Button>(R.id.btnSave) 74 //保存ボタンをタップできないように変更 75 btnSave.isEnabled = false 76 } 77 78 //リストがタップされたときの処理が記述されたメンバクラス 79 private inner class ListItemClickListener : AdapterView.OnItemClickListener { 80 override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { 81 //タップされた行番号をフィールドの主キーIDに代入 82 _cocktailId = position 83 //タップされた行のデータを取得。これがカクテル名となるので、フィールドに代入。 84 _cocktailName = parent.getItemAtPosition(position) as String 85 //カクテル名を表示するTextViewを取得 86 val tvCocktailName = findViewById<TextView>(R.id.tvCocktailName) 87 //カクテル名を表示するTextViewに表示カクテル名を設定 88 tvCocktailName.text = _cocktailName 89 //保存ボタンを取得 90 val btnSave = findViewById<Button>(R.id.btnSave) 91 //保存ボタンをタップできるように設定 92 btnSave.isEnabled = true 93 94 //データベースヘルパーオブジェクトからデータベース接続オブジェクトを取得 95 val db = _helper.writableDatabase 96 //主キーによる検索SQL文字列の用意 97 val sql = "SELECT * FROM cocktailmemos WHERE _id = ${_cocktailId}" 98 //SQLの実行 99 val cursor = db.rawQuery(sql, null) 100 //データベースから取得した値を格納する変数の用意。データがなかった時のための初期値も用意 101 var note = "" 102 //SQL実行の戻り値であるカーソルオブジェクトをループさせてデータベース内のデータを取得 103 while(cursor.moveToNext()) { 104 val idxNote = cursor.getColumnIndex("note") 105 //カラムのインデックス値を元に実際のデータを取得 106 note = cursor.getString(idxNote) 107 } 108 //感想のEditTextの各画面部品を取得しデータベースの値を反映 109 val etNote = findViewById<EditText>(R.id.etNote) 110 etNote.setText(note) 111 } 112 } 113} 114
kotlin
1package com.example.databasesample 2 3import android.content.Context 4import android.database.sqlite.SQLiteDatabase 5import android.database.sqlite.SQLiteOpenHelper 6 7class DatabaseHelper(context: Context): SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) { 8 //クラス内のprivate定数を宣言するためにcompanion objectブロックとする。 9 companion object { 10 //データベースファイル名の定数フィールド 11 private const val DATABASE_NAME = "cocktailmemo.db" 12 //バージョン情報の定数フィールド 13 private const val DATABASE_VERSION = 1 14 } 15 16 override fun onCreate(db: SQLiteDatabase) { 17 //テーブル作成用SQL文字列の作成 18 val sb = StringBuilder() 19 sb.append("CREATE TABLE cocktailmemos (") 20 sb.append("_id INTEGER PRIMARY KEY,") 21 sb.append("name TEXT,") 22 sb.append("note TEXT") 23 sb.append(");") 24 val sql = sb.toString() 25 26 //SQLの実行 27 db.execSQL(sql) 28 } 29 30 override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {} 31}
試したこと
ここに問題に対して試したことを記載してください。
補足情報(FW/ツールのバージョンなど)
Android 3.5.3
『Parameter 'view' is never used』は警告ではないですか?アプリが落ちる原因だとは思えません。Logcatのログ等は調べましたか?
それについては調べていませんでした。さっき調べたところ、このような文が出てきました。
2020-09-22 22:24:10.129 6072-6072/com.example.databasesample W/Settings: Setting device_provisioned has moved from android.provider.Settings.Secure to android.provider.Settings.Global.
2020-09-22 22:24:10.129 6072-6099/com.example.databasesample I/.databasesampl: Starting profile saver IsSaveProfileNow end.
2020-09-22 22:24:10.130 6072-6072/com.example.databasesample V/HiTouch_HiTouchSensor: User setup is finished.
2020-09-22 22:24:10.235 6072-6072/com.example.databasesample I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
2020-09-22 22:24:10.254 6072-6072/com.example.databasesample V/AudioManager: playSoundEffect effectType: 0
2020-09-22 22:24:10.255 6072-6072/com.example.databasesample V/AudioManager: querySoundEffectsEnabled...
2020-09-22 22:24:10.290 6072-6072/com.example.databasesample E/SQLiteLog: (1)
2020-09-22 22:24:10.290 6072-6072/com.example.databasesample D/AndroidRuntime: Shutting down VM
--------- beginning of crash
2020-09-22 22:24:10.296 6072-6072/com.example.databasesample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.databasesample, PID: 6072
android.database.sqlite.SQLiteException: no such column: _id (Sqlite code 1 SQLITE_ERROR): , while compiling: SELECT * FROM cocktailmemos WHERE _id = 5, (OS error - 2:No such file or directory)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:948)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:559)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:603)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:63)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1493)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1427)
at com.example.databasesample.MainActivity$ListItemClickListener.onItemClick(MainActivity.kt:100)
at android.widget.AdapterView.performItemClick(AdapterView.java:321)
at android.widget.AbsListView.performItemClick(AbsListView.java:1234)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3234)
at android.widget.AbsListView$3.run(AbsListView.java:4210)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
2020-09-22 22:24:10.348 6072-6072/com.example.databasesample I/Process: Sending signal. PID: 6072 SIG: 9
回答1件
あなたの回答
tips
プレビュー