Android StudioでSQLite接続を試みましたが、
アプリを起動した瞬間にアプリが強制終了されてしまいます。
ソースコードに原因があるのか、
SQLiteの使用に別の設定が必要なのか、
原因がわかる方ご教授お願いいたします。
ちなみにソースコードは【Androidアプリ開発の教科書】に書かれていたものを
そのまま使用しました。
エミュレータ(Pixel 3a)、実機ともに試しましたがだめでした。
8/27 10:37追記
アプリが強制終了されたときのエラーログを追記します。
また、本文に誤りがあったので訂正ですが、
強制終了のタイミングはアプリ起動時ではなく、
リストビューの項目を選択したときでした。
2019-08-27 10:35:34.074 12191-12191/com.example.databasesample E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.databasesample, PID: 12191 android.database.sqlite.SQLiteException: Can't downgrade database from version 3 to 1 at android.database.sqlite.SQLiteOpenHelper.onDowngrade(SQLiteOpenHelper.java:522) at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:396) at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:298) at com.example.databasesample.CocktailMemoActivity$ListItemClickListener.onItemClick(CocktailMemoActivity.java:71) at android.widget.AdapterView.performItemClick(AdapterView.java:318) at android.widget.AbsListView.performItemClick(AbsListView.java:1159) at android.widget.AbsListView$PerformClick.run(AbsListView.java:3136) at android.widget.AbsListView$3.run(AbsListView.java:4052) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
//DatabaseHelper.java package com.example.databasesample; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "cocktailmemo.db"; private static final int DATABASE_VERSION = 1; public DatabaseHelper(Context context){ super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db){ StringBuilder sb = new StringBuilder(); sb.append("CREATE TABLE cocktailmemo("); sb.append("_id INTEGER PRIMARY KEY,"); sb.append("name TEXT,"); sb.append("note TEXT"); sb.append(");"); String sql = sb.toString(); db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ } }
//CocktailMemoActivity.java package com.example.databasesample; import androidx.appcompat.app.AppCompatActivity; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteStatement; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; public class CocktailMemoActivity extends AppCompatActivity { int _cocktailId = -1; String _cocktailName = ""; TextView _tvCocktailName; Button _btnSave; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_cocktail_memo); _tvCocktailName = findViewById(R.id.tvCocktailName); _btnSave = findViewById(R.id.btnSave); ListView lvCocktail = findViewById(R.id.lvCocktail); lvCocktail.setOnItemClickListener(new ListItemClickListener()); } public void onSaveButtonClick(View view) { EditText etNote = findViewById(R.id.etNote); String note = etNote.getText().toString(); DatabaseHelper helper = new DatabaseHelper(CocktailMemoActivity.this); SQLiteDatabase db = helper.getWritableDatabase(); try{ String sqlDelete = "DELETE FROM cocktailmemo WHERE _id = ?"; SQLiteStatement stmt = db.compileStatement(sqlDelete); stmt.bindLong(1, _cocktailId); stmt.bindString(2,_cocktailName); stmt.bindString(3,note); stmt.executeInsert(); } finally{ db.close(); } _tvCocktailName.setText(getString(R.string.tv_name)); etNote.setText(""); _btnSave.setEnabled(false); } private class ListItemClickListener implements AdapterView.OnItemClickListener{ @Override public void onItemClick(AdapterView<?>parent, View view, int position, long id){ _cocktailId = position; _cocktailName = (String)parent.getItemAtPosition(position); _tvCocktailName.setText(_cocktailName); _btnSave.setEnabled(true); DatabaseHelper helper = new DatabaseHelper(CocktailMemoActivity.this); SQLiteDatabase db = helper.getWritableDatabase(); try{ String sql = "SELECT * FROM cocktailmemo WHERE _id = "+ _cocktailId; Cursor cursor = db.rawQuery(sql,null); String note = ""; while(cursor.moveToNext()){ int idxNote = cursor.getColumnIndex("note"); note = cursor.getString(idxNote); } EditText etNote = findViewById(R.id.etNote); etNote.setText(note); } finally{ db.close(); } } } }
//activity_cocktail_memo.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/lvCocktail" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginBottom="10dp" android:layout_weight="0.6" android:entries="@array/lv_cocktaillist"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tv_lb_name" android:textSize="20sp"/> <TextView android:id="@+id/tvCocktailName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tv_name" android:textSize="20sp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="@string/tv_lb_note" android:textSize="20sp"/> <EditText android:id="@+id/etNote" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.4" android:gravity="top" android:inputType="textMultiLine"/> <Button android:id="@+id/btnSave" android:layout_width="match_parent" android:layout_height="wrap_content" android:enabled="false" android:onClick="onSaveButtonClick" android:text="@string/btn_save"/> </LinearLayout>
エラーログとか何かしら残っていませんか?
確認して内容を提示するとアドバイスを得やすくなると思います
>Can't downgrade database from version 3 to 1
からすると導入されているSQLiteのバージョンは3ということでしょうか。
DATABASE_VERSION=1 としたのはどういう意図がありますか?
意味も分からず本に書いてあった通りにしていました。
DATABASE_VERSION=3として実行したところ、
リストビュー選択までは問題なく稼働しましたが、
保存ボタンをクリックするとやはり強制終了してしまいます。
以下、そのときのエラーログです。
2019-08-27 10:56:55.738 16086-16086/com.example.databasesample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.databasesample, PID: 16086
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at android.view.View.performClick(View.java:6663)
at android.view.View.performClickInternal(View.java:6635)
at android.view.View.access$3100(View.java:794)
at android.view.View$PerformClick.run(View.java:26199)
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)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:6663)
at android.view.View.performClickInternal(View.java:6635)
at android.view.View.access$3100(View.java:794)
at android.view.View$PerformClick.run(View.java:26199)
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)
Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 2 because the index is out of range. The statement has 1 parameters.
at android.database.sqlite.SQLiteProgram.bind(SQLiteProgram.java:217)
at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:171)
at com.example.databasesample.CocktailMemoActivity.onSaveButtonClick(CocktailMemoActivity.java:47)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:6663)
at android.view.View.performClickInternal(View.java:6635)
at android.view.View.access$3100(View.java:794)
at android.view.View$PerformClick.run(View.java:26199)
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)
要件変わってます。
一度自己解決として別質問としてください。
ただ、エラーはきちんと読んでください。
https://qiita.com/cannorin/items/eb062aae88bfe2ad6fe5
回答1件
あなたの回答
tips
プレビュー