【小ネタ】Androidアプリのデータ保存でSharedPreferencesを使ってみる

私がAndroidアプリの開発を行っていて、ちょくちょく使ってはいたのですが何かはよくわかっていなかったSharedPreferencesの使い方を改めて整理します。

https://developer.android.com/training/data-storage/shared-preferences?hl=ja

SharedPreferencesは比較的小さなデータを保存するときに使うようです。
データベースに保存するほどではないデータや、アプリの設定を保存するときにいいみたいです。

# 詳細

### データの取得
`sharedPreferences.getString(key,default)`
第一引数が`key`になっていて取得したい値を指定します。
第二引数はデフォルトの値で、第一引数で指定した`key`の値がなければ第二引数の値を返します。

```Java
SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);

String userName = sharedPreferences.getString("username", "default_name");
int userAge = sharedPreferences.getInt("user_age", 0);
boolean isStatus = sharedPreferences.getBoolean("is_logged_in", false);
```

### データの保存
保存するデータの型に合わせて`putString`,`putInt`,`putBoolean`の後に`editor.apply()`でデータの保存を行います。

```Java
SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();

editor.putString("username", "名前");
editor.putInt("user_age", 18);
editor.putBoolean("is_logged_in", true);

editor.apply();
```

# データの取得および保存
実際の利用例を以下に示します。

```MainActivity.java
package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button bt_save;
    private EditText et_name;
    private EditText et_age;
    private Switch sw_status;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bt_save = findViewById(R.id.bt_save);
        et_name = findViewById(R.id.et_name);
        et_age = findViewById(R.id.et_age);
        sw_status = findViewById(R.id.sw_status);

        // SharedPreferencesを宣言
        SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        // データの取得
        String userName = sharedPreferences.getString("username", "default_name");
        et_name.setText(userName);
        
        int userAge = sharedPreferences.getInt("user_age", 0);
        et_age.setText(String.valueOf(userAge));
        
        boolean isStatus = sharedPreferences.getBoolean("is_logged_in", false);
        sw_status.setChecked(isStatus);

        // 保存ボタンタップ時の処理
        bt_save.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String name = et_name.getText().toString();
                int age = Integer.parseInt(et_age.getText().toString());
                boolean status = sw_status.isChecked();

                // データの保存
                editor.putString("username", name);
                editor.putInt("user_age", age);
                editor.putBoolean("is_logged_in", status);

                editor.apply();

                Toast msg = Toast.makeText(getBaseContext(), "保存しました", Toast.LENGTH_LONG);
                msg.show();
            }
        });
    }
}
```

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        tools:ignore="MissingConstraints">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            tools:ignore="MissingConstraints">

            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:text="名前："
                android:textSize="28dp"/>

            <EditText
                android:id="@+id/et_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:hint="名前を入力してください"
                android:textSize="28dp"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            tools:ignore="MissingConstraints">

            <TextView
                android:id="@+id/textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:text="年齢："
                android:textSize="28dp"/>

            <EditText
                android:id="@+id/et_age"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:hint="年齢を入力してください"
                android:textSize="28dp"
                android:inputType="number"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            tools:ignore="MissingConstraints">

            <TextView
                android:id="@+id/textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:text="ステータス："
                android:textSize="28dp"/>

            <Switch
                android:id="@+id/sw_status"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"/>

        </LinearLayout>

        <Button
            android:id="@+id/bt_save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="保存"
            android:textSize="20dp"/>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

```

# 終わりに
これまで何となく使っていたSharedPreferencesについて整理できました。
簡単に保存できるので、DBを使って保存するほどのことじゃないときに使いやすいと思います。
これを記載している2025年3月時点だとDataStoreというSharedPreferencesの欠点を直したものがあるようなので、次回はこちらについて整理して記事を書きます。