2011年1月20日木曜日

アプリのデータを保存する(プリファレンス編)

前回 アプリのデータを保存する(基本編)では、ファイルの保存について説明しましたが、
今回は「設定値の保存」を可能にする「プリファレンス」について学んでいきたいと思います。

プリファレンスの形式とデータ型

プリファレンスは、「"キー" => 値」という形式でデータを保存します。
キーと値には5種類の型があり、これはJavaの「変数と値」の関係と似ています。

保存できるデータ型は以下の通りです。

1. boolean
2. float
3. int
4. long
5. String

データの保存方法

以下のように、SharedPreferences の SharedPreferences.Editor でデータを保存します。
SharedPreferences pref =
    getSharedPreferences("pref", MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE);
Editor e = pref.edit();
e.putString("key", "value");
e.commit();

オペレーションモードは3種類

プリファレンスでは、MODE_APPENDを除いた3種類のオペレーションモードが指定可能です。

定数説明
MODE_PRIVATE作成したアプリのみ読み書きできる
MODE_WORLD_READABLE他アプリに読み込み権を与える
MODE_WORLD_WRITEABLE他アプリに書き込み権を与える

プリファレンスの実体

また、プリファレンスの実体は、内部記憶媒体に保存されたXMLファイルです。
中身は、以下のように、キーが<string>タグの name 属性、値が value 属性または要素値という形になっています。

※コマンドラインから表示
# adb shell
# cat /data/data/"パッケージ名"/shared_prefs/"ファイル名".xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <boolean name="key_boolean" value="false" />
    <float name="key_float" value="0.0" />
    <int name="key_int" value="0" />
    <long name="key_long" value="0" />
    <string name="key_String">value</string>
</map>

3種類のプリファレンス作成方法

代表的なプリファレンス作成方法は、以下の3種類があります。
いずれも、戻り値は SharedPreferences です。

1. Context#getSharedPreferences(String name, int mode)
2. Activity#getPreferences(int mode)
3. PreferenceManager.getDefaultSharedPreferences(Context context)

具体的な使用方法は以下になります。
package com.blogspot.androlab.example;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;

public class MainActivity extends Activity {
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // 代表的なプリファレンス作成方法は3種類ある
  SharedPreferences prefNameFree;
  SharedPreferences prefNameClass;
  SharedPreferences prefNamePackage;

  // 任意のファイル名で作成する方法
  prefNameFree = getSharedPreferences("shared", MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE);
  Editor e = prefNameFree.edit();
  e.putString("key", "value");
  e.commit();

  // アクティビティごとに作成する方法
  prefNameClass = getPreferences(MODE_PRIVATE);
  e = prefNameClass.edit();
  e.putString("key", "value");
  e.commit();

  // デフォルトプリファレンスを作成する方法(常に MODE_PRIVATE)
  prefNamePackage = PreferenceManager.getDefaultSharedPreferences(this);
  e = prefNamePackage.edit();
  e.putString("key", "value");
  e.commit();
 }
}

※コマンドラインから表示
# adb shell
# ls /data/data/com.blogspot.androlab.example/shared_prefs/
com.blogspot.androlab.example_preferences.xml
MainActivity.xml
shared.xml

プリファレンスの削除方法

設定値の削除は、以下の2つのメソッドを用います。
SharedPreferences.Editor#remove(String key)
SharedPreferences.Editor#commit()

一括削除は、以下の2つのメソッドを用います。
SharedPreferences.Editor#clear()
SharedPreferences.Editor#commit()

なお、ファイル自体を削除するメソッドはありません。
アンインストールしてアプリごと消すか、以下のコードをご参考ください。
public static void deleteSharedPreferences(Context context) {
  try {
   ApplicationInfo info =
    context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
   File dir = new File(info.dataDir.concat(File.separator).concat("shared_prefs").concat(File.separator));
   if (dir.isDirectory())
    for (String file : dir.list()) new File(dir, file).delete();
  } catch (NameNotFoundException e) {
   e.printStackTrace();
  }
}

プリファレンスを初期化する

最後に、プリファレンスの初期化について説明します。

まず、以下の2つのXMLファイルを用意します。
これは、ユーザによる設定が行われていない場合のプリファレンスの初期値になります。

/res/xml/default_values.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 android:key="applicationPreference" android:title="Weight Class Settings">
 <ListPreference
  android:key="weight_class"
  android:defaultValue="126"
  android:title="Hozumi Hasegawa"
  android:summary="Featherweight"
  android:entries="@array/weight_classes"
  android:entryValues="@array/weight_pounds"
  android:dialogTitle="Please set his weight class." />
</PreferenceScreen>

/res/values/arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <string-array name="weight_classes">
  <item>Featherweight</item>
  <item>Super bantamweight</item>
  <item>Bantamweight</item>
 </string-array>
 <string-array name="weight_pounds">
  <item>126</item>
  <item>122</item>
  <item>118</item>
 </string-array>
</resources>

次に、下記のメソッドで上記のXMLファイルを指定します。

PreferenceManager.setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)

MainActivity.java
package com.blogspot.androlab.example;

import java.io.File;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;

public class MainActivity extends Activity {
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  PreferenceManager.setDefaultValues(this, "weight_class", MODE_PRIVATE, R.xml.default_values, true);
 }
}

以上の手順を踏むと、プリファレンスの実体で説明した形式に変換されて、内部記憶領域に保存されます。

※コマンドラインから表示
# adb shell
# cat /data/data/com.blogspot.androlab.example/shared_prefs/weight_class.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
  <string name="weight_class">126</string>
</map>

0 件のコメント:

コメントを投稿