EntryNavi : « iTunes COM for Windows SDK のダウンロード場所 | メイン | Windows Phone Marketplaceの有料アプリ公開に必要な書類(W-8BEN)の書き方 »

CategoryNavi : メイン -> コンピューター -> 開発 -> Java(Android)

消えないIntent

誰かこれの解決方法教えてください。

流れとしてはこんな感じ
1.アプリAからIntentでアプリBを呼び出す。
  その時、Intent#putExtraで付加情報をつける。
  で、Activity#startActivtyする。
2.アプリBでなんか処理をしてfinishで終了する。
  この時、当然Intent#getIntExtra系のメソッドで1で付加した情報が読める。
3.Homeキー長押しから再度アプリBを起動する。
4.アプリBでIntent#getIntExtra系のメソッドでまた1で付加した情報が読めてしまう。
4'.ランチャーから起動した場合は読めなくなってる。

試してみたこと
a.アプリBでIntent#removeExtraで該当の情報を消す
b.アプリBでIntent#putExtraで該当の情報を上書き
c.アプリBでActivity#setIntent(new Intent())で上書き
d.アプリBでFLAG_ACTIVITY_NO_HISTORYフラグを付けて呼び出す。(2011/1/31追記)
(c , dでアイデアくれてお二人ありがとうございます。)

残念ながらどれも失敗。

Activityのソース見たほうが早いんじゃない?ってアドバイスもらったのでサラッと見て見てみました。
おそらくですが、タスクを管理している所からインテントのインスタンスをもらっていました。
なので、試してみたことcは当然ダメなのですがaとbは効いてもよさそうなのに効かないので本当の実態は別でいるのではないかと予想してます。つまりクラスのコピーが渡ってきてる。
ホームキー長押しの履歴機能は当時の呼び出し状況をそのまま再現している勢いに見えます。(2011/1/31追記) 強調しますが適当に予想してますので事実とは全く違う可能性大です。


とは言いつつもこの動きのままではいろいろと困るので若干弱点というか未検証の部分があるものの対策を考えました。
簡単に言うと、呼び出すときにタイムスタンプを付けて同じ情報を2度拾わないって方法です。
前回の情報はアプリケーションクラスに保存します。
具体的には以下のような感じ。
と、言ってもサンプルすらいらないと思いますが。(しかも端折ってる。)

呼び出し方
Intent intent = new Intent();
intent.setAction("jp.hogehoge.ACTION_HOGE");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("FLAG", true);
intent.putExtra("TIMESTAMP", System.currentTimeMillis());   //これタイムスタンプ
startActivity(intent);

呼び出され方
public class HogeApplication extends Application {
	private long _prevTimestamp = 0;		//前回のタイムスタンプ

	/**
	 * 前回のタイムスタンプ
	 * @param _prevTimestamp the _prevTimestamp to set
	 */
	public void setPrevTimestamp(long _prevTimestamp) {
		this._prevTimestamp = _prevTimestamp;
	}
	/**
	 * 前回のタイムスタンプ
	 * @return the _prevTimestamp
	 */
	public long getPrevTimestamp() {
		return _prevTimestamp;
	}
}

public class HogeActivity extends Activity

	private void checkIntent(){
		Intent intent = getIntent();
		HogeApplication app = (HogeApplication)getApplication();
		if(intent == null){
		}else if(app == null){
		}else{
			boolean flg = intent.getBooleanExtra("FLAG", false));
			long timestamp = intent.getLongExtra("TIMESTAMP", 0);
			if(app.getPrevTimestamp() == timestamp){
				//前回と同じなので実行しない
			}else{
				//今回はなにか実行する
				app.setPrevTimestamp(timestamp);
			}
		}
	}
}
※呼び出される側はインテントをウケれるようにマニフェストを記述してください。


Intentの使い方間違えてるかもしれない&そもそもこんな状況になる作り方が悪いのかわからないので誰か教えて!
(重要なことなので2回言っちゃった)


ずいぶん前に@gabuさんに相談して「消せないっすね~」的な話にはなってたのですがやっぱり気になったので記事にしました。


<Category : Java(Android)>

コメント (2)

ss.momonga:

現在Launcherアプリを作成しており、色々と調べている最中にこのサイトにたどり着きました。
この件、今更なので解決済み or どうでも良くなっているかも知れませんが。

また、私も適当な推測であり、未検証なのでどこまで正しいか分かりません。

ホームキー長押しでアプリ履歴から起動する時、RecentTaskInfoでintentそのもの履歴を取得してようなので、この例にあるアプリBで何とか消す方法は無理と思います。
アプリAでintentを作成する際にFLAG_ACTIVITY_NO_HISTORYを立てればRecentTaskInfoに載らないようになるんじゃないかと。
間接的ですが、ホームキー長押しからgetExtrasされることはなくなります。

あやね:

> ss.momonga さん
情報ありがとうございます。参考にします。
特別解決はしてないのですが何とかなってるので放置しちゃってます^^;

コメントを投稿

検索

Google

サイドフィード

track feed 理ろぐ
人気ブログランキング - 理ろぐ
Powered by
Movable Type 3.34