可悲的是,在(请参阅亚历克斯洛克伍德的回答)ActivityCompat.startActivityForResult()
中不太正确。Fragments
几个星期以来,我惊叹于 Google 从未给我们提供ActivityCompat
与 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 在请求代码上使用了一些奇怪的字节移位,以确保onActivityResult()
之后只调用调用 Fragment。现在由于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);
}
}
在您喜欢的任何地方复制该方法并从您的 Fragment 中使用它。它onActivityResult()
应该被调用。
更新:支持库 v23.2 已发布,现在似乎startActivityFromFragment(Fragment fragment, Intent intent, int requestCode, Bundle options)
可以完成工作了 :)