Android中RegisterForActivityResult的回调result始终为空问题
问题原因与解决方案
你的核心问题是误用了ActivityResultContracts.TakePicture的返回值类型:这个合约的回调返回的是bool类型(表示拍照是否成功完成),而非ActivityResult对象,所以你强转后得到的activityResult必然是null。
具体修正步骤
1. 修正ActivityResultCallback类
把回调的泛型类型改为bool,不再尝试转成ActivityResult:
public class ActivityResultCallback : Java.Lang.Object, IActivityResultCallback<bool> { public EventHandler<bool> OnActivityResultCalled; public void OnActivityResult(bool result) { OnActivityResultCalled?.Invoke(this, result); } }
2. 调整Photo类中的回调注册与处理逻辑
- 注册Launcher时匹配泛型类型
- 在回调中根据返回的bool值判断拍照状态:
true:用户成功拍摄并保存了照片false:用户取消了拍照,或者拍照过程失败
修改后的Photo类关键部分:
protected override void OnCreate(Bundle bundle) { try { _activityResultCallback = new ActivityResultCallback(); // 订阅bool类型的回调事件 _activityResultCallback.OnActivityResultCalled += ActivityResultCallback_ActivityResultCalled; // 明确指定TakePicture合约的泛型类型为bool _activityResultLauncher = RegisterForActivityResult(new ActivityResultContracts.TakePicture(), _activityResultCallback); // ... 其余原有代码不变 } } // 回调方法参数改为bool类型 private void ActivityResultCallback_ActivityResultCalled(object sender, bool isSuccess) { if (!isSuccess) { // 用户取消拍照或拍照失败,清理空文件并标记状态 PictureTaken = false; // 如果文件已创建但未写入内容,删除避免后续混淆 if (App._file != null && App._file.Exists() && App._file.Length() == 0) { App._file.Delete(); } return; } // 拍照成功,执行原有图片处理逻辑 try { int height = 260; int width = 200; App.bitmap = App._file.Path.LoadAndResizeBitmap(width, height); Bitmap bitmap = App.bitmap; var filePath = App._file.AbsolutePath; var stream = new System.IO.FileStream(filePath, System.IO.FileMode.Create); bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream); stream.Close(); MyImageView.SetImageBitmap(App.bitmap); bitmap = null; App.bitmap = null; PictureTaken = true; } catch (Exception ex) { PictureTaken = false; // 错误处理 } }
额外注意点
TakePicture合约会直接将拍摄的照片写入你传入的Uri对应的文件,成功时返回true,失败/取消返回false,不需要再从Intent中获取数据- 每次点击拍照按钮时,最好重新生成文件路径,避免重复覆盖旧文件(你的代码已经做了这一步,但要确保取消时删除空文件)
内容的提问来源于stack exchange,提问作者Prescott Chartier
相关产品推荐
相关产品推荐

