質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

8676閲覧

[Android] Toggleボタンの状態の保持

noriyo_tcp

総合スコア15

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

2クリップ

投稿2014/07/30 09:45

toggleボタンを押すとサービス開始(タイマー作動、ボタンの表記はResetになる)、またボタンを押すとサービス停止(タイマーリセット)というアプリを作っているのですが、バックグラウンドからアプリに復帰したときに、toggleボタンが元の状態に戻っていまいます(タイマーは動作を続けている)
どうすればボタンの状態を保持できるのでしょうか?

以下がコードです(一部省略)

MainActivity.java
`
// (一部省略)
import android.app.Activity;
import android.content.Intent;
// 以下必要なものをimport

public class MainActivity extends Activity implements OnCheckedChangeListener {

static TextView timer;
static ToggleButton toggle;
private static long settingTime = 60000;

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

timer = (TextView) findViewById(R.id.timer); toggle = (ToggleButton) findViewById(R.id.toggleButton1); // 初期時間設定 showTimer(getSettingTime()); // リスナ登録 toggle.setOnCheckedChangeListener(this);

}

TimerService timerTask = new TimerService();
private Intent timerIntent;

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// サービスを開始か停止
if (isChecked == true) {
Toast.makeText(this, "Start", Toast.LENGTH_SHORT).show();
// Start service
startService();
} else {
// Stop service
stopService(timerIntent);
// 設定した時間にリセット
showTimer(getSettingTime());
}
}

public void startService() {
// Serviceに設定時間を送ってサービス開始
timerIntent = new Intent(MainActivity.this, TimerService.class);
timerIntent.putExtra("settingTime", getSettingTime());

startService(timerIntent);

}
}
`

TimerService.java
`
// (一部省略)
import android.app.Service;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.widget.Toast;

public class TimerService extends Service {
protected MyCountDownTimer cdt;

@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}

@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// タイマーのインスタンス生成&スタート
cdt = new MyCountDownTimer(intent.getExtras().getLong("settingTime"), 500);
cdt.start();

return super.onStartCommand(intent, flags, startId);

}

@Override
public void onDestroy() {
// タイマーインスタンスのキャンセル&破棄
cdt.cancel();
cdt = null;

super.onDestroy();

}

public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
MainActivity.showTimer(millisInFuture);
}

@Override public void onFinish() { MainActivity.timer.setText("0:00"); Toast.makeText(getApplicationContext(), "Finished!", Toast.LENGTH_SHORT).show(); // 設定時間にリセット MainActivity.showTimer(MainActivity.getSettingTime()); // トグルボタンをfalse MainActivity.toggle.setChecked(false); // Stop service stopSelf(); } @Override public void onTick(long millisUntilFinished) { // 残り時間表示 MainActivity.showTimer(millisUntilFinished); }

}
}
`

試してみたのは

  • SharedPreferences(トグルボタンの状態を保持したい)
  • MainActivityのonResume()にいろいろ記述(ライフサイクルがよくわかってない)

などですが、うまくいきません。
Logを仕込んでみたところ、アプリがバックグラウンドに回ると、onPause() -> onStop()と状態遷移して、そこから復帰するときにonCreate() -> onStart() -> onResume()と遷移しているのは分かったのですけど、そこでデフォルトに戻ってしまっているのかな?と。(xmlでのToggleButtonの属性にandroid:checked="false"と記述している)
setChecked(Boolean)で指定してもコールバックメソッドを呼んでしまうので、どうしたものかなと。
長くなりましたが、とにかくトグルボタンの状態を保持したいのです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

onCreateのListener登録の前にsetCheckedで状態を設定してあげるのはどうでしょうか?

投稿2014/07/31 02:34

omochi

総合スコア410

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

noriyo_tcp

2014/07/31 05:29

ホームボタンで閉じたあとの復帰はいいのですけど、バックボタンからの復帰ではうまくいきませんね。ふむー。
omochi

2014/07/31 06:53

簡単なサンプルを作成して試したのですが、ToggleButtonをONにして他のアプリを起動しバックボタンで戻ってもToggleButtonはONのままです。 Activityが破棄されなければ状態は残っていると思います。 他でToggleButtonに値を設定している箇所などありませんか?
noriyo_tcp

2014/07/31 09:11

Log.v(<ライフサイクル名>, toggle.isChecked())でチェック状態を取得してみましたが、 // アプリ起動 onCreate(890): toggle is false onStart(890): toggle is false onResume(890): toggle is false // 他のアプリ起動から戻るボタン、アイコンクリックで復帰 onPause(890): toggle is true onStop(890): toggle is true onStart(890): toggle is true onResume(890): toggle is true // 戻るボタンで閉じてからアイコンクリックでの復帰 onPause(890): toggle is true onStop(890): toggle is true onDestroy(890): toggle is true onCreate(890): toggle is false onStart(890): toggle is false onResume(890): toggle is false onDestroyされても状態は維持されているようですが、その後のonCreate()で結局元に戻ってしまっているようです。 閉じる前に状態を保持して、onCreate()の時にそれを読み込めばいいんですかね? 他の箇所では値を設定してないんですよねー。
omochi

2014/07/31 09:22

最初の解答と同じになってしまいますが、onCreateのListener登録の前にサービスから今の状態を取得してsetCheckedに設定すればいいと思います。
noriyo_tcp

2014/08/01 04:15

Bundleを用意して public static Bundle outState = new Bundle(); onResume()で toggle.setChecked(outState.getBoolean("toggleKey", toggle.isChecked())); toggle.setOnCheckedChangeListener(this); onCreate()でも同様の記述をして、 onPause()で outState.putBoolean("toggleKey", toggle.isChecked()); toggle.setOnCheckedChangeListener(this); としました。 stopService()もstartService()と同様に、 public void stopService() { timerIntent = new Intent(MainActivity.this, TimerService.class); stopService(timerIntent); } を作って、リスナ側からは引数無しでそのまま呼び出すという形にしました。 これでバックボタンからの復帰でもトグルボタンの状態が維持されてはいます(ごくたまにresetを押しても表示が戻らない現象がありますが・・・) 一応onSaveInstanceStateとonRestoreInstanceStateも用意しましたが、あるときとないときとのちがいはよくわかりません(挙動は変わりない・・・ように見える) いやはやお手数をおかけしました・・・。 参考記事 http://stackoverflow.com/questions/12334991/preserving-toggle-button-state-on-my-activity
omochi

2014/08/01 08:24

解決?されたようで良かったです。 そしてあまりお役にたてなくてすみませんでした。 最後に Serviceが状態を把握しているわけですから、Bundleに保持するのでなくServiceから取得する方がスマートだと思います。 また、Service側でカウントダウンが終了した場合にトグルの状態の不整合が起こるように思えます。 Service取得について以下のサイト記事が参考になるかと思います http://www.atmarkit.co.jp/ait/articles/0906/18/news102.html
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問