Intent投げて返りが欲しいときの注意点

Filed in Android, Java, prog

 画像をギャラリーから取ってこようと思ってstartActivityForResult使ってごにょごにょやってたらonActivityResultが呼ばれたり呼ばれなかったりしたので調べてみたことをメモ。
 適当なActivityを起動して結果を貰いたいときにはstartActivityForResultを使う。

// 画像取得ボタンの実装
// Intentの帰りを受けるためにActivityクラス内で定義する
@Override
public void onClick(View v) {
Intent intent = new Intent();
// 画像取得
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0);
}

 受け取る方は受け取りたいActivityにonActivityResultを書いとくと読んでもらえる。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == RESULT_OK) {
Uri uri = (Uri)data.getData();
String imgFileName = uri.getPath();
(略)
}
}

 で、適当に作って適当に遊んでたらなんとなく動いたのでコードとか誰ともかぶらなさそうなのに変えようと思って変えてみた。

// 画像取得ボタンの実装
// Intentの帰りを受けるためにActivityクラス内で定義する
@Override
public void onClick(View v) {
Intent intent = new Intent();
// 画像取得
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0xDEADBEAF);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0xDEADBEAF && resultCode == RESULT_OK) {
Uri uri = (Uri)data.getData();
String imgFileName = uri.getPath();
(略)
}
}

 でもこれだとonActivityResultが呼ばれない。なんでやねん。
 で、差を見て理由がわからなかったので調べてみた。
 まずstartActivityForResultのコードを見てみた。ソースはAOSPから拾ってきたICSのr1。
 ※markdownで書いてる都合上4スペースを1タブで変換してます。
Activity.java: startActivityForResult

Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}

 上記の通りstartActivityForResultではsendActivityResultで結果を返す。
 sendActivityResultが呼ばれるためにはexecStartActivityからActivityResultが返ってこないといけない。
 execStartActivityの中身を見てみると、ActivityResultオブジェクトを返すところが以下のようになっている。
Instrumentation.java: execStartActivity

final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}

 ActivityThreadが監視しているActivityMonitorの数だけ上記のコードが回されるんだけど細かいところはおいといて、returnのところを見るとリクエストコードが非負の整数でないと結果を返そうとしていない。
 リクエストコードはstartActivityForResultで渡している値なので、試したコードを再掲すると。

// 画像取得ボタンの実装
// Intentの帰りを受けるためにActivityクラス内で定義する
@Override
public void onClick(View v) {
Intent intent = new Intent();
// 画像取得
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0xDEADBEAF);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0xDEADBEAF && resultCode == RESULT_OK) {
Uri uri = (Uri)data.getData();
String imgFileName = uri.getPath();
(略)
}
}

 ばっちりリクエストコードが負の整数!
 そりゃないぜセニョール! と思ってAndroid Developersを確認してみたら。。。
> Parameters
> intent The intent to start.
> requestCode If >= 0, this code will be returned in onActivityResult() when the activity exits.
 ばっちり書いてあった(ノ∀`)アチャー
 いつものことだけどドキュメントよく読めってことですね。サーセンwwwww


Feedback

Comments

No Responses to “Intent投げて返りが欲しいときの注意点”

Trackbacks

  1. java.util.ListIteratorのドキュメントが嘘つきな件(´・ω・`) » あおいろヨゾラ

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
Oenology Post Formats
Click to view/hide

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
Posts Calendar
Click to view/hide
2012年2月
« 1月   5月 »
 1234
567891011
12131415161718
19202122232425
26272829  

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
アーカイブ
Click to view/hide

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
最近の投稿
Click to view/hide