android SharedPreferences 使い方 保存方法
解決済
回答 2
投稿 ・編集
- 評価
- クリップ 0
- VIEW 3,674
まだまだ勉強したての初心者です。
androidの開発中でゲームを作成していて、
今回のゲーム結果をA部分にタイム表示し、それをBの部分に保存(前回のデータを上回っていたら書き換え)
という風にしたいのですが、まず保存自体が四苦八苦しておりできません。
コード
SharedPreferences pref = this.getSharedPreferences("user_data", Context.MODE_PRIVATE);
// プリファレンスに書き込むためのEditorオブジェクト取得
Editor editor = pref.edit();
// user_id というキーで値を保存
editor.putString("user_id", inputs);//inputsは秒数を表示しているtextview
// ここで実際にファイルに書き込む
editor.commit();
// 保存されている値を呼び出し
((SharedPreferences) tv2).getInt("user_id", -1);//textviewのtv2に表示したい
今記述しているコードは上記ですがエラーが出ます。
デバッグで見てみてもtv2には反映されていません。
上記の正しい記述や解決方法、できれば前回の記録との比較方法も教えて頂けたらありがたいです。
ご教授よろしくお願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
質問とコードを照らし合わせてもその辺があまり読み取れないです。
ですので追記のコードでおかしそうな部分を指摘します。
editor.commit()を2回していますが、その間に値の変更処理はないので最後のeditor.commit()は意味が無いです。
ちなみに以下のメソッドの第2引数はデフォルト値です。
値が存在しなかった場合に取得する値です。
pref1.getString("g2byou", inputs)
的外れでしたらすみません。
追記:
適当なサンプルを実装してみました。
ボタンを押下するとランダム値と最大値がTextViewに表示されます。
最大値はPrefarenceに保存しているのでアプリ再起動後も有効です。
レイアウトはTextView2つ、Button1つなので適当に作成してください。
private TextView textViewA;
private TextView textViewB;
private SharedPreferences pref;
private int max;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewA = (TextView) findViewById(R.id.textView1);
textViewB = (TextView) findViewById(R.id.textView2);
Button button = (Button) findViewById(R.id.button1);
pref = getSharedPreferences("user_data", MODE_PRIVATE);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int value = (int) (Math.random() * 1000);
if (value > max) {
max = value;
pref.edit().putInt("max", max).commit();
textViewB.setText("" + max);
}
textViewA.setText("" + value);
}
});
max = pref.getInt("max", 0);
textViewA.setText("");
textViewB.setText("" + max);
}
追記2:
なるべく変更しないで修正しました。
コンパイルも行っていないのでそのまま動くか不明です。
画面遷移で変更した部分があります。
各画面(2,3,4)から遷移する場合に画面IDをIntentに"INPUTid"としてセットしてあげてください。なので画面毎に"INPUT","INPUT3","INPUT4"と分けないで"INPUT","INPUTs","INPUTms"で統一して修正してください。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
Intent intent = getIntent();
TextView textview1 = (TextView) findViewById(R.id.textView1);
TextView textview3 = (TextView) findViewById(R.id.textView3);
TextView textview5 = (TextView) findViewById(R.id.textView5);
TextView tv1 = (TextView) findViewById(R.id.tv1);
TextView tv2 = (TextView) findViewById(R.id.tv2);
TextView tv3 = (TextView) findViewById(R.id.tv3);
TextView tv4 = (TextView) findViewById(R.id.tv4);
TextView tv5 = (TextView) findViewById(R.id.tv5);
TextView tv6 = (TextView) findViewById(R.id.tv6);
TextView tv7 = (TextView) findViewById(R.id.tv7);
TextView tv8 = (TextView) findViewById(R.id.tv8);
TextView tv9 = (TextView) findViewById(R.id.tv9);
int id = intent.getIntExtra("INPUTid", -1); // 画面idを送る
String hun = intent.getStringExtra("INPUT");
String byou = intent.getStringExtra("INPUTs");
String mbyou = intent.getStringExtra("INPUTms");
textview1.setText(hun);
textview3.setText(byou);
textview5.setText(mbyou);
int ihun = Integer.valueOf(hun);
int ibyou = Integer.valueOf(byou);
int imbyou = Integer.valueOf(mbyou);
showScore(tv1, tv2, tv3, 2, id, ihun, ibyou, imbyou);
showScore(tv4, tv5, tv6, 3, id, ihun, ibyou, imbyou);
showScore(tv7, tv8, tv9, 4, id, ihun, ibyou, imbyou);
}
private void showScore(TextView tf, TextView ts, TextView tt, int id, int rcvId, int hun, int byou, int mbyou) {
SharedPreferences pref = getSharedPreferences("user_data", MODE_PRIVATE);
int minhun = pref.getInt("g" + id + "hun", 60);
int minbyou = pref.getInt("g" + id + "byou", 60);
int minmbyou = pref.getInt("g" + id + "mbyou", 1000);
if (minhun >= 60) {
tf.setText("");
ts.setText("");
tt.setText("");
} else {
tf.setText(minhun + "");
ts.setText(minbyou + "");
tt.setText(minmbyou + "");
}
if (id == rcvId) {
long msec = (hun * 60 + byou) * 1000 + mbyou;
if ((minhun * 60 + minbyou) * 1000 + minmbyou > msec) {// 更新してたら上書き
pref.edit().putInt("g" + id + "hun", hun).putInt("g" + id + "byou", byou)
.putInt("g" + id + "mbyou", mbyou).commit();
tf.setText(hun + "");
ts.setText(byou + "");
tt.setText(mbyou + "");
}
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
putString しているのに getInt なんですか?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.23%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2014/10/16 12:02
わかりにくい記述で申し訳ございません。
A,B,Cすべてtextviewです。Aのtextviewには今回の記録(秒数)
Bのtextviewには過去最高記録を保存(更新したら塗り替え)
Cのtextviewは今回の保存がちゃんとなっているかのテスト用です。
editor.commit()を消して第2引数も消してみたのですが相変わらず
表示はされるのですが保存されず前回のデータが消えてしまいます。
2014/10/16 13:12
あるなら投稿した方がみなさん解答しやすいですよ。
2014/10/16 13:42
お役にたてなかっらたごめんなさい。
2014/10/16 22:10
教えていただいたコードがイメージ通りです!
ただ先ほどから試しているのですが、
まだ私の技術不足で自分のコードに当てはめる事ができません。
よろしかったら教えて頂けないでしょうか。
わかりやすいようにと思って省略して載せていたのですが逆にわかりにくくしてたんですね。申し訳ないです。
画面2、3、4からの結果を、
下の画面5のコードのtextview1(分),textview3(秒),textview5(ミリ秒)に表示させ、
過去最高を上回っていたらそれぞれ
画面2の分は tv1(分),tv2(秒),tv3(ミリ秒)に表示と保存
画面3の分は tv4(分),tv5(秒),tv6(ミリ秒)に表示と保存
画面4の分は tv7(分),tv8(秒),tv9(ミリ秒)に表示と保存
としたいのです。
今はそれぞれからの画面からの結果をtextview1,3,5からの結果を表示としかできていません。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gamen5);
Intent intent=getIntent();
TextView textview1=(TextView) findViewById(R.id.textView1);
TextView textview3=(TextView) findViewById(R.id.textView3);
TextView textview5=(TextView) findViewById(R.id.textView5);
TextView tv1=(TextView) findViewById(R.id.tv1);
TextView tv2=(TextView) findViewById(R.id.tv2);
TextView tv3=(TextView) findViewById(R.id.tv3);
String hun = null;
String byou = null;
String mbyou = null;
TextView tv4=(TextView) findViewById(R.id.tv4);
TextView tv5=(TextView) findViewById(R.id.tv5);
TextView tv6=(TextView) findViewById(R.id.tv6);
String hun3 = null;
String byou3 = null;
String mbyou3 = null;
TextView tv7=(TextView) findViewById(R.id.tv7);
TextView tv8=(TextView) findViewById(R.id.tv8);
TextView tv9=(TextView) findViewById(R.id.tv9);
String hun4 = null;
String byou4 = null;
String mbyou4 = null;
hun = intent.getStringExtra("INPUT");
byou = intent.getStringExtra("INPUTs");
mbyou = intent.getStringExtra("INPUTms");
hun3 = intent.getStringExtra("INPUT3");
byou3 = intent.getStringExtra("INPUT3s");
mbyou3 = intent.getStringExtra("INPUT3ms");
hun4 = intent.getStringExtra("INPUT4");
byou4 = intent.getStringExtra("INPUT4s");
mbyou4 = intent.getStringExtra("INPUT4ms");
if(hun != null && byou != null){
//画面2からのデータ
String input=intent.getStringExtra("INPUT");
textview1.setText(input);
String inputs=intent.getStringExtra("INPUTs");
textview3.setText(inputs);
String inputms=intent.getStringExtra("INPUTms");
textview5.setText(inputms);
// MODE_PRIVATEでこのアプリだけが使用できるように設定
SharedPreferences pref1 = getSharedPreferences("user_data",MODE_PRIVATE);
SharedPreferences.Editor editor = pref1.edit();
// プリファレンスに書き込むためのEditorオブジェクト取得
// g2hun というキーで値を保存
editor.putString("g2hun", input);
editor.putString("g2byou", inputs);
editor.putString("g2mbyou", inputms);
// ここで実際にファイルに書き込む
editor.commit();
tv1.setText(pref1.getString("g2hun", inputs),BufferType.NORMAL);//textviewのpreference保存の記述
tv2.setText(pref1.getString("g2byou", inputs),BufferType.NORMAL);
tv3.setText(pref1.getString("g2mbyou", inputms),BufferType.NORMAL);
}else if(hun3 != null && byou3 != null){
//画面3からのデータ
上記とほぼ一緒なので省略
}else {
//画面4からのデータ
上記とほぼ一緒なので省略
}
}
2014/10/17 13:32
2014/10/17 23:28
長いコード書いて頂いて本当にありがたいです。
お手数おかけして申し訳ないです。
今教えて頂いた通りに、上記コードにし、画面の2、3、4、も変更したのですが上記の結果表示画面に切り替わるタイミングでエラーになり強制終了します。
//各画面(2,3,4)から遷移する場合に画面IDをIntentに"INPUTid"としてセットしてあげてください。
これは画面2であれば、
intent.putExtra("INPUTid",2);
intent.putExtra("INPUT", input);
intent.putExtra("INPUTs", inputs);
intent.putExtra("INPUTms", inputms);
としているのですが間違っているのでしょうか。
intent.putExtra("INPUTid",2);
長々と質問ばかりしてすみません。
2014/10/19 03:43
エミュレータが強制終了になるのを解決できません。
1つずつ調べているのですが
おそらく、
int minhun = pref.getInt("g2hun", Integer.MAX_VALUE);
int minbyou = pref.getInt("g2byou", Integer.MAX_VALUE);
int minmbyou = pref.getInt("g2mbyou", Integer.MAX_VALUE);
long minmsec = (minhun * 60 + minbyou) * 1000 + minmbyou;
の部分がエラーの原因かと思うのですが、解決方法がわかりません。
2014/10/20 20:05
int minhun = pref.getInt("g2hun", 59);
int minbyou = pref.getInt("g2byou", 59);
int minmbyou = pref.getInt("g2mbyou", 999);
long minmsec = (minhun * 60 + minbyou) * 1000 + minmbyou;
2014/10/21 02:01
上記に変えてみたのですがやはり強制終了になります。
何度も質問ばかりで申し訳無かったです、丁寧に教えて頂いてすごく嬉しいです!
ベストアンサー付けさせて頂きました!
自分でももっと悩んで試行錯誤してみます。
もしomochiさんが何か原因が判明して、お手すきでしたらアドバイス頂けたら嬉しいです。
ありがとうございました。
2014/10/21 02:53
user_dataが<評価中のエラー>
g2hun
g2byou
g2mbyouも<評価中のエラー>でした。なので
minhun
minbyou
minmbyou
minmsecも<評価中のエラー>となっていました。
ここに原因があると思うのですが、難しいです。。
お手すきな時間ありましたらご教授頂けたらありがたいです。
2014/10/21 12:44
2014/10/21 15:13
inputms 7
inputs 13
input 00
id 2
minhun <評価中のエラー>
minbyou <評価中のエラー>
minmbyou <評価中のエラー>
minmsec <評価中のエラー>
editor (id=830034201720)
と出ています。
教えて頂いたコードをそのまま使用するとその画面に切り替わるタイミングで強制終了します。
(eclipseのデバッグの方はActivityThreadというページが出てきます。画面上には赤字でソースが見つかりませんでした。と出ています。)
なので自分で少しづつ入力していき、エミュレータで起動確認しながら入力しているのですが、やはり
int minhun = pref.getInt("g2hun", 59);
int minbyou = pref.getInt("g2byou", 59);
int minmbyou = pref.getInt("g2mbyou", 999);
long minmsec = (minhun * 60 + minbyou) * 1000 + minmbyou;
を記入してエミュで確認したらページが切り替わるタイミングで終了します。
この時も、eclipseにはActivityThreadが出てきて、ソースが~と表示されています。
どうしたら良いでしょうか。
ご教授よろしくお願いします。
2014/10/21 15:15
その前の画面2,3,4いずれかが終了して、その上記の結果の画面に切り替わるタイミングです。
2014/10/21 16:59
その後に再度インストールしてください。
以前のプリファレンスが型違いで残っていてキャストに失敗している可能性があります。
*Logcatで例外ログが出力されているはずです。LogCatはデバッグする上でとても重要なので確認方法を覚えましょう。
2014/10/21 17:48
2014/10/22 01:33
エミュレータ上のアプリをアンインストールして、再度教えて頂いたコードを当てはめたのですが、同じタイミングでエラーとなり強制終了してしまいます。
エラーの時に出てきたLogcatをerrorで絞り込んで全て下記に載せました。これの事でしょうか?
Logcatも勉強します。
10-21 16:26:36.728: E/AndroidRuntime(1869): FATAL EXCEPTION: main
10-21 16:26:36.728: E/AndroidRuntime(1869): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.nekotest/com.example.nekotest.SaigoActivity}: java.lang.NullPointerException
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.app.ActivityThread.access$600(ActivityThread.java:141)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.os.Handler.dispatchMessage(Handler.java:99)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.os.Looper.loop(Looper.java:137)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.app.ActivityThread.main(ActivityThread.java:5039)
10-21 16:26:36.728: E/AndroidRuntime(1869): at java.lang.reflect.Method.invokeNative(Native Method)
10-21 16:26:36.728: E/AndroidRuntime(1869): at java.lang.reflect.Method.invoke(Method.java:511)
10-21 16:26:36.728: E/AndroidRuntime(1869): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-21 16:26:36.728: E/AndroidRuntime(1869): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-21 16:26:36.728: E/AndroidRuntime(1869): at dalvik.system.NativeStart.main(Native Method)
10-21 16:26:36.728: E/AndroidRuntime(1869): Caused by: java.lang.NullPointerException
10-21 16:26:36.728: E/AndroidRuntime(1869): at com.example.nekotest.SaigoActivity.onCreate(SaigoActivity.java:49)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.app.Activity.performCreate(Activity.java:5104)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
10-21 16:26:36.728: E/AndroidRuntime(1869): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
10-21 16:26:36.728: E/AndroidRuntime(1869): ... 11 more
2014/10/22 17:05
SaigoActivity.java:49行目でNullPointerExceptionが発生しています。
49行目で何か値が取得できていなかったり初期化されていない変数があると思います。
2014/10/23 00:41
49行目はこの部分です。デバッグで値を見ようとしてもZygoteInit.javaと言うところにいきみれません。
45 int id = intent.getIntExtra("INPUTid", -1); // 画面idを送る
46 String hun = intent.getStringExtra("INPUT");
47 String byou = intent.getStringExtra("INPUTs");
48 String mbyou = intent.getStringExtra("INPUTms");
49 textview1.setText(hun);
50 textview3.setText(byou);
51 textview5.setText(mbyou);
アプリ作成の最後の最後で考えても進まず足踏み状態でくじけそうですが、ここまできたら完成させたいです。
長々とお付き合いして頂き申し訳ないですが、ご教授頂きたいです。
よろしくお願いします。
2014/10/23 11:37
E/AndroidRuntime(2563): FATAL EXCEPTION: main
E/AndroidRuntime(2563): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.nekotest/com.example.nekotest.SaigoActivity}: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
E/AndroidRuntime(2563): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
E/AndroidRuntime(2563): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
E/AndroidRuntime(2563): at android.app.ActivityThread.access$600(ActivityThread.java:141)
E/AndroidRuntime(2563): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
E/AndroidRuntime(2563): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(2563): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(2563): at android.app.ActivityThread.main(ActivityThread.java:5103)
E/AndroidRuntime(2563): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(2563): at java.lang.reflect.Method.invoke(Method.java:525)
E/AndroidRuntime(2563): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
E/AndroidRuntime(2563): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime(2563): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(2563): Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
E/AndroidRuntime(2563): at android.app.SharedPreferencesImpl.getInt(SharedPreferencesImpl.java:240)
E/AndroidRuntime(2563): at com.example.nekotest.SaigoActivity.showScore(SaigoActivity.java:63)
E/AndroidRuntime(2563): at com.example.nekotest.SaigoActivity.onCreate(SaigoActivity.java:56)
E/AndroidRuntime(2563): at android.app.Activity.performCreate(Activity.java:5133)
E/AndroidRuntime(2563): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime(2563): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
E/AndroidRuntime(2563): ... 11 more
56行目と63行目でキャストできていないと言ってるのでしょうか。
56 showScore(tv1, tv2, tv3, 2 , id, ihun, ibyou, imbyou);
57 showScore(tv4, tv5, tv6, 3 , id, ihun, ibyou, imbyou);
58 showScore(tv7, tv8, tv9, 4 , id, ihun, ibyou, imbyou);
}
62 private void showScore(TextView tf, TextView ts, TextView tt, int id, int r cvId, int hun, int byou, int mbyou) {
63 int minhun = pref.getInt("g" + id + "hun", 60);
64 int minbyou = pref.getInt("g" + id + "byou", 60);
65 int minmbyou = pref.getInt("g" + id + "mbyou", 1000);
2014/10/23 15:08
おそらく以前に指摘した古いプリファレンスがStringで残っているためだと思います。アンインストールをしてから再度インストールしてみてください。
2014/10/23 15:16
上記でNullPointerExceptionが発生しているのはtextview1に値をいれていないからです。
メンバ変数のtextview1にfindViewByIdで値を入れる必要があります。ローカル変数でスコープを上書きしているとメンバ変数はnullのままです。
私のコードそのままだとNullPointerExceptionは発生しないはずです。
2014/10/23 15:29
2014/10/23 22:47
お世話になっております。
ありがとうございます。
アンインストールの心配もあったので新しいプロジェクトを作成し実行したら教えて頂いたコードのままでできました!!
もう自分の実力ではまだまだかかるであろう問題に長々とお付き合い頂いて本当に助かりました!
デバッグやLogCatの事など自分の先にするべき事もわかりました!
本当にありがとうございました。