SQLiteを使用してTimePickerDialogで選択した時刻を保存する【Android Studio, Java】(ソースコード付き)

スポンサーリンク
Android Studio

SQLiteってどうやって使えばいいの?

時計画面で選択した時刻を保存したい

こういったお悩みを解決いたします。

サンプルとして、TimePickerDialogで選択した時刻をデータベースに保存します。

TimePickerDialogのそもそもの使い方が不明な方は、以下の記事を参考にしてみてください。

TimePickerDialogで時刻を設定(選択)する方法[Android Studio, Java]

当記事はJavaで実装しています。

Kotlinで実装予定の方は以下の記事を参考にしてみてください。

qiita.com

スポンサーリンク

環境

– Android Studio 4.0

– 使用言語 Java

スポンサーリンク

データ保存の流れ

  1.  EditTextをタップし、時計(TimePickerDialog)を表示する
  2.  時計で時刻を選択する
  3.  ダイアログで”OK”ボタンを押すと、選択された時刻をデータベースに保存する

f:id:pikaoichan:20200822174327p:plain

当記事では3について詳しく解説します。

1,2について詳しく知りたい方は以下を参考にしてください。

TimePickerDialogで時刻を設定(選択)する方法[Android Studio, Java]

実装

activity_main.xmlと string.xmlについては↑の記事と同じものを使用しています。

Javaクラスを見ていきましょう。

MainActivity.java

package com.example.sqlitetimesample;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
  private EditText _etTimePicker;
  private DatabaseHelper _dbHelper;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    _etTimePicker = findViewById(R.id.etTimePicker);
    _etTimePicker.setOnClickListener(new etOnClickListener());
    _dbHelper = new DatabaseHelper(MainActivity.this);
  }
  public class etOnClickListener implements View.OnClickListener{
    @Override
    public void onClick(View view) {    //タップされたときの処理
      TimePickerDialogFragment timePickerDialogFragment = new TimePickerDialogFragment(); //TimePickerDialogFragmentクラスのインスタンスを生成
      timePickerDialogFragment.show(getSupportFragmentManager(), "TimePickerDialogFragment"); //ダイアログを表示
    }
  }
  public void setTextToEditText(String timeText) {    //EditTextに文字列をセットする関数
    _etTimePicker.setText(timeText);
  }
  public DatabaseHelper get_dbHelper(){
    return _dbHelper;
  }
}

Activityではデータベースに関する記述はあまりしていません。

データベースを管理するクラスであるDatabaseHelperのインスタンスをフィールドとして持ち、ゲッターを介してアクセスできるようにしているくらいです。

DatabaseHelper.java

package com.example.sqlitetimesample;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
  private static final String DATABASE_NAME = "SQLiteTimeSample.db";   //データベースファイル名
  private static final int DATABASE_VERSION = 1;
  public  static final int SAMPLE_ID = 0; //サンプルで使用するレコードID(主キー)
  public DatabaseHelper(Context context){ //コンストラクタ
    super(context, DATABASE_NAME, null, DATABASE_VERSION);  //親クラスのコンストラクタを呼び出し
  }
  @Override
  public void onCreate(SQLiteDatabase db) {
    /* テーブル作成用SQL文字列の作成 */
    StringBuilder sb = new StringBuilder();
    sb.append("CREATE TABLE SQLiteTimeSample (");
    sb.append("_id INTEGER PRIMARY KEY,");
    sb.append("Hour INTEGER,");
    sb.append("Minute INTEGER");
    sb.append(");");
    String sql = sb.toString();
    db.execSQL(sql);
  }
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  }
  public static boolean CheckDBExist(SQLiteDatabase db){  //データベース内にすでにレコードが存在するかどうかチェックする
    boolean dbExist = false;
    final Cursor cursor = db.rawQuery("SELECT * FROM SQLiteTimeSample WHERE _id = " + DatabaseHelper.SAMPLE_ID, null);
    if(cursor.moveToFirst()) dbExist = true;
    return dbExist;
  }
}

データベースを管理するクラスです。SQLiteOpenHelperクラスを拡張しています。

フィールドとしてデータベース名(テーブル一つ一つ)、バージョン、レコードID(主キー)を持っています。今回の例では、データベースに登録されるレコードは最大でも1つなので、IDをstatic変数として定義しています。

コンストラクタ内では特にすることはないので、親クラスのコンストラクタを呼び出しています。

onCreateでテーブルそのものを定義します。(カラム名や型など)

onUpgradeは、端末内のデータベースのバージョンとスクリプト内のバージョンが異なるときに実行されます。今回の例だと、DATABASE_VERSIONがバージョンを表しています。コンストラクタでデータベースとバージョンを紐づけています。

アプリの更新に伴ってデータベースに何らかの変更が加わるときは、ここに処理を記述する必要がありますね。

最後に、CheckDBExistという自作関数を定義しています。これは、引数で指定したデータベースにレコードが登録されているかどうかを返す関数です。Cursorオブジェクトはデータベーステーブルの情報を一行ずつ取り出す際に便利です。(今回は最大で1行しかありませんが…)

TimePickerDialogFragment.java

package com.example.sqlitetimesample;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.os.Bundle;
import android.widget.TimePicker;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
public class TimePickerDialogFragment extends DialogFragment {
  @NonNull
  @Override
  public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    final MainActivity mainActivity = (MainActivity) getActivity();
    final SQLiteDatabase db = mainActivity.get_dbHelper().getWritableDatabase();
    final boolean dbExist = DatabaseHelper.CheckDBExist(db);
    TimePickerDialog timePickerDialog = new TimePickerDialog(
      mainActivity,
      new TimePickerDialog.OnTimeSetListener() {
        @Override
        public void onTimeSet(TimePicker view, int hour, int minute) {  //時刻が設定されたときの処理
          if(dbExist){
            String sqlUpdate = "UPDATE SQLiteTimeSample SET Hour = ?, Minute = ? WHERE _id = ?";
            SQLiteStatement stmt = db.compileStatement(sqlUpdate);
            stmt.bindLong(1, hour);
            stmt.bindLong(2, minute);
            stmt.bindLong(3, DatabaseHelper.SAMPLE_ID);
            stmt.executeUpdateDelete();
          }
          else {
            String sqlInsert = "INSERT INTO SQLiteTimeSample (_id, Hour, Minute) VALUES (?, ?, ?)";
            SQLiteStatement stmt = db.compileStatement(sqlInsert);
            stmt.bindLong(1, DatabaseHelper.SAMPLE_ID);
            stmt.bindLong(2, hour);
            stmt.bindLong(3, minute);
            stmt.executeInsert();
          }
          String timeText = hour + ":" + String.format("%02d", minute);    //EditTextに表示する文字列
          mainActivity.setTextToEditText(timeText);
        }
      },
      12, //初期値(時)
      0,  //初期値(分)
      true
    );
    return timePickerDialog;
  }
}

DatePickerDialogのコンストラクタの第2引数の中のonDataSetでデータベースに登録or更新する処理を記述しています。

処理は非常にシンプルで、すでにレコードが存在するなら更新処理を、存在しないなら登録処理を行っているだけです。

おわりに

いかがでしたでしょうか。

今回は、非常に単純なサンプルで1レコードしか想定していませんが、多くのレコードを登録するときはIDをしっかり考えて与える必要がありますので注意してください。

以上です。

※日付でも非常に似たようなことができます。↓

SQLiteを使用してDatePickerDialogで選択した日付を保存する【Android Studio, Java】(ソースコード付き)

コメント

タイトルとURLをコピーしました