残念ながら、ActivityCompat.startActivityForResult()
うまく機能しませんFragments
(Alex Lockwood の回答を参照)。数週間、GoogleActivityCompat
が Fragment のstartActivityForResult()
. 彼らは何を考えていた?! しかし、私はアイデアを思いつきました: メソッドが実際にどのように実装されているか見てみましょう。
実際のところ、startActivityForResult()
Fragment は Activity のものとは異なります (こちらを参照)。
public void startActivityForResult(Intent intent, int requestCode) {
if (mActivity == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
mActivity.startActivityFromFragment(this, intent, requestCode);
}
現在startActivityFromFragment()
は次のようになっています (こちらを参照):
public void startActivityFromFragment(Fragment fragment, Intent intent,
int requestCode) {
if (requestCode == -1) {
super.startActivityForResult(intent, -1);
return;
}
if ((requestCode&0xffff0000) != 0) {
throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
}
super.startActivityForResult(intent,
((fragment.mIndex + 1) << 16) + (requestCode & 0xffff));
}
Google は、リクエスト コードで奇妙なバイト シフトを使用して、呼び出し元の Fragment のみがonActivityResult()
後で呼び出されるようにします。は何も提供してActivityCompat
いないためstartActivityFromFragment()
、残された唯一のオプションは自分で実装することです。パッケージのプライベート フィールドにアクセスするには、リフレクションが必要ですmIndex
。
public static void startActivityForResult(Fragment fragment, Intent intent,
int requestCode, Bundle options) {
if (Build.VERSION.SDK_INT >= 16) {
if ((requestCode & 0xffff0000) != 0) {
throw new IllegalArgumentException("Can only use lower 16 bits" +
" for requestCode");
}
if (requestCode != -1) {
try {
Field mIndex = Fragment.class.getDeclaredField("mIndex");
mIndex.setAccessible(true);
requestCode = ((mIndex.getInt(this) + 1) << 16) + (requestCode & 0xffff);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
ActivityCompat.startActivityForResult(fragment.getActivity(), intent,
requestCode, options);
} else {
fragment.getActivity().startActivityFromFragment(this, intent, requestCode);
}
}
そのメソッドを好きな場所にコピーして、フラグメントから使用します。必要に応じonActivityResult()
て呼び出されます。
更新:サポートライブラリv23.2がリリースされ、startActivityFromFragment(Fragment fragment, Intent intent, int requestCode, Bundle options)
現在は機能しているようです:)