LoginSignup
12
19

More than 3 years have passed since last update.

【ぶっちゃけAndroidアプリ開発】SQLiteデータベースにアクセスして画面に表示するサンプル

Last updated at Posted at 2020-01-01

sqliteで作成したテーブルにアクセスして、Activityに表示する簡単なサンプルを作成しました。
動くサンプルコードが欲しい人のために、簡単な解説とともに載せておきます。

Android StudioでEmpty Activityで新規プロジェクト作成し、コピペすれば動くはずです。

<前提>
作成日:2020年1月1日
AndroidStudio 3.5.3
targetSdkVersion 26
CompileSdkVersion 29

・Empty Activityの雛形を元に作成。

1.データベースファイルの作成

test.csv
1,東京都庁,東京都新宿区西新宿2-8-1,03-5321-1111,metro.tokyo.jp
2,神奈川県庁,神奈川県横浜市中区日本大通1,045-210-1111,pref.kanagawa.jp
3,埼玉県庁,埼玉県さいたま市浦和区高砂3-15-1,048-824-2111,pref.saitama.lg.jp
4,千葉県庁,千葉県千葉市中央市場町1-1,043-223-2110,pref.chiba.lg.jp
5,静岡県庁,静岡県静岡市葵区追手町9-6,054-221-2455,pref.shizuoka.jp

・住所録ちっくなcsvファイルをインポートし、sqliteを使用してデータベースファイル「test.db」を作成する。
・テーブル名は「addressbook」、項目は seq(integer),name(text),address(text),phone(text),mail(text) の5つ。
・データベースファイルの作成方法は、「【ぶっちゃけAndroidアプリ開発】sqliteでデータベースを作成する」を参照。

2.データベースファイルをプロジェクトに追加する

(1)Assetsフォルダの作成

・ツールウィンドウのモジュールを右クリックして、Assetsフォルダを追加する。
スクリーンショット 2020-01-01 12.56.05.png

(2)データベースファイルの追加

・作成した「test.db」ファイルをAssetsフォルダにコピペする。
スクリーンショット 2020-01-01 17.56.20.png

3.SQLiteOpenHelperクラスの実装

・SQLiteOpenHelperを継承したクラスを実装する。
・実装例は「Y.A.M.さんのページ」を参照させていただきました。

DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {

    private static String DB_NAME = "test";
    private static String DB_NAME_ASSET = "test.db";
    private static final int DATABASE_VERSION = 1;

    private final Context mContext;
    private final File mDatabasePath;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DATABASE_VERSION);
        mContext = context;
        mDatabasePath = mContext.getDatabasePath(DB_NAME);
    }

    /**
     * asset に格納したデータベースをコピーするための空のデータベースを作成する
     */
    public void createDatabase() throws IOException {
        boolean dbExist = checkDatabaseExists();

        if (dbExist) {
            // すでにデータベースは作成されている
        } else {
            // このメソッドを呼ぶことで、空のデータベースがアプリのデフォルトシステムパスに作られる
            SQLiteDatabase db = getReadableDatabase();
            db.close();

            try {
                // asset に格納したデータベースをコピーする
                copyDatabaseFromAsset();

                String dbPath = mDatabasePath.getAbsolutePath();
                SQLiteDatabase checkDb = null;
                try {
                    checkDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
                } catch (SQLiteException e) {
                }

                if (checkDb != null) {
                    checkDb.setVersion(DATABASE_VERSION);
                    checkDb.close();
                }

            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    /**
     * 再コピーを防止するために、すでにデータベースがあるかどうか判定する
     *
     * @return 存在している場合 {@code true}
     */
    private boolean checkDatabaseExists() {
        String dbPath = mDatabasePath.getAbsolutePath();

        SQLiteDatabase checkDb = null;
        try {
            checkDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            // データベースはまだ存在していない
        }

        if (checkDb == null) {
            // データベースはまだ存在していない
            return false;
        }

        int oldVersion = checkDb.getVersion();
        int newVersion = DATABASE_VERSION;

        if (oldVersion == newVersion) {
            // データベースは存在していて最新
            checkDb.close();
            return true;
        }

        // データベースが存在していて最新ではないので削除
        File f = new File(dbPath);
        f.delete();
        return false;
    }

    /**
     * asset に格納したデーだベースをデフォルトのデータベースパスに作成したからのデータベースにコピーする
     */
    private void copyDatabaseFromAsset() throws IOException{

        // asset 内のデータベースファイルにアクセス
        InputStream mInput = mContext.getAssets().open(DB_NAME_ASSET);

        // デフォルトのデータベースパスに作成した空のDB
        OutputStream mOutput = new FileOutputStream(mDatabasePath);

        // コピー
        byte[] buffer = new byte[1024];
        int size;
        while ((size = mInput.read(buffer)) > 0) {
            mOutput.write(buffer, 0, size);
        }

        // Close the streams
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

・createDatabaseメソッドでデータベースをプログラムで使用できるようにする。AssetsフォルダのデータベースをAndroid端末内にコピーする。(そうしないと使えないらしい)

4.MainActivityからデータベースアクセス

MainActivity.java
public class MainActivity extends AppCompatActivity {

    private DatabaseHelper helper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = findViewById(R.id.textview);

        helper = new DatabaseHelper(this);
        try {
            helper.createDatabase();
        }
        catch (IOException e) {
            throw new Error("Unable to create database");
        }
        StringBuilder builder = new StringBuilder();

        SQLiteDatabase db = helper.getReadableDatabase();
        String sql = "select seq, name, address, phone, mail from addressbook";

        try {
            Cursor cursor = db.rawQuery(sql, null);
            while(cursor.moveToNext()) {
                builder.append(cursor.getInt(0) + " ");
                builder.append(cursor.getString(1) + " ");
                builder.append(cursor.getString(2) + " ");
                builder.append(cursor.getString(3) + " ");
                builder.append(cursor.getString(4) + "\n");
            }
        } finally {
            db.close();
        }
        textView.setText(builder.toString());
    }
}

・helperオブジェクトを作成する。
・createDatabaseメソッドでデータベースを使用できる状態にする。
・getReadableDatabaseメソッドで読み取り専用データベースをオープンする。
・sqlで全レコードをselectし、TextViewに表示する。
・このサンプルは読み取り専用だが、getWritableDatabaseで読み書きできるデータベースとしてオープンできる。

5.レイアウト

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

・TextViewのidに「textview」を指定してください。

6.実行結果

20200101_173927.jpg

12
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
19