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

スポンサーリンク
Android Studio

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

カレンダーで選択した日付を保存したい

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

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

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

DatePickerDialogで日付を設定(選択)する方法【Android Studio, Java】

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

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

qiita.com

スポンサーリンク

環境

– Android Studio 4.0

– 使用言語 Java

スポンサーリンク

データ保存の流れ

  1.  EditTextをタップし、カレンダーを表示する
  2.  カレンダーで日付を選択する
  3.  ダイアログで”OK”ボタンを押すと、選択された日付をデータベースに保存する

f:id:pikaoichan:20200817125312p:plain

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

1.2.の段階はこちらの記事で丁寧に解説しております。

DatePickerDialogで日付を設定(選択)する方法【Android Studio, Java】

実装

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

ここでは主にJavaクラスを見ていきましょう。

MainActivity.java

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

アクティビティではデータベースに関する記述はあまりしていません。

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

DatabaseHelper.java

package com.example.sqlitesample;
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 = "SQLiteSample.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 SQLiteSample (");
    sb.append("_id INTEGER PRIMARY KEY,");
    sb.append("Year INTEGER,");
    sb.append("Month INTEGER,");
    sb.append("Day 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 SQLiteSample WHERE _id = " + DatabaseHelper.SAMPLE_ID, null);
    if(cursor.moveToFirst()) dbExist = true;
    return dbExist;
  }
}

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

フィールドとしてデータベース名(テーブル)、バージョン、レコードID(主キー)を持っています。

今回の例では、データベースに登録するレコードは最大で1つなので、IDをstatic変数として定義しています。

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

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

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

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

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

より詳しく知りたい方は公式リファレンスを参照してみてください。

Cursor  |  Android Developers

DatePickerDialogFragment.java

package com.example.sqlitesample;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.os.Bundle;
import android.widget.DatePicker;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import java.util.Calendar;
public class DatePickerDialogFragment extends DialogFragment {
  @NonNull
  @Override
  public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { //ダイアログを生成する処理
    Calendar calendar = Calendar.getInstance(); //現在の日時情報を持つカレンダーオブジェクトを取得
    final MainActivity mainActivity = (MainActivity) getActivity(); //現在のアクティビティを取得
    final SQLiteDatabase db = mainActivity.get_dbHelper().getWritableDatabase();
    final boolean dbExist = DatabaseHelper.CheckDBExist(db);    //データベースにすでにレコードがあるかどうか
    DatePickerDialog datePickerDialog = new DatePickerDialog(   //DatePickerDialogオブジェクトを生成
      mainActivity,   //第1引数(Activity)
      new DatePickerDialog.OnDateSetListener() {  //第2引数(日付が設定されたときのリスナ)
        @Override
        public void onDateSet(DatePicker datePicker, int year, int month, int dayOfMonth) { //日付が設定されたときの処理
          if(dbExist){    //すでにレコードが存在するとき
            String sqlUpdate = "UPDATE SQLiteSample SET Year = ?, Month = ?, Day = ? WHERE _id = ?";
            SQLiteStatement stmt = db.compileStatement(sqlUpdate);
            stmt.bindLong(1, year);
            stmt.bindLong(2, month);
            stmt.bindLong(3, dayOfMonth);
            stmt.bindLong(4, DatabaseHelper.SAMPLE_ID);
            stmt.executeUpdateDelete();
          }
          else {          //レコードが存在しないとき
            String sqlInsert = "INSERT INTO SQLiteSample (_id, Year, Month, Day) VALUES (?, ?, ?, ?)";
            SQLiteStatement stmt = db.compileStatement(sqlInsert);
            stmt.bindLong(1, DatabaseHelper.SAMPLE_ID);
            stmt.bindLong(2, year);
            stmt.bindLong(3, month);
            stmt.bindLong(4, dayOfMonth);
            stmt.executeInsert();
          }
          String dateText = (month + 1) + "月" + dayOfMonth + "日"; //"〇月×日"の文字列を生成
          mainActivity.setTextToEditText(dateText);   //EditTextに文字列を設定
        }
      },
      calendar.get(Calendar.YEAR),    //第3引数(西暦初期値)
      calendar.get(Calendar.MONTH),   //第4引数(月初期値)
      calendar.get(Calendar.DAY_OF_MONTH) //第5引数(日初期値)
    );
    return datePickerDialog;
  }
}
DatePickerDialogのコンストラクタの第2引数の中のonDataSetでデータベースに登録or更新する処理を記述しています。処理は非常にシンプルで、すでにレコードが存在するなら更新処理を、存在しないなら登録処理を行っているだけです。

おわりに

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

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

以上です。

コメント

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