我已经将旧的StartActivityForResult
代码转换为新的RegisterForActivityResult
,因为StartActivityForResult
在android API 29和更高版本中贬值了。我的新代码工作得很完美,除了class ActivityResultCallback
中的result
总是空。我需要能够知道用户何时取消拍照,当他们点击后退按钮时,否则,应用程序会崩溃(如果之前的图片不存在),或者之前拍摄的图片会被再次处理。我的代码(仅显示相关代码):
public class Photo : AppCompatActivity
{
public ImageView MyImageView;
public ImageButton camerabutton;
public bool PictureTaken = false;
private CurrentSubjectInfo MySubjectInfo;
private ActivityResultCallback _activityResultCallback;
private ActivityResultLauncher _activityResultLauncher;
private Uri uri;
protected override void OnCreate(Bundle bundle)
{
try
{
_activityResultCallback = new ActivityResultCallback();
_activityResultCallback.OnActivityResultCalled += ActivityResultCallback_ActivityResultCalled;
_activityResultLauncher = RegisterForActivityResult(new ActivityResultContracts.TakePicture(), _activityResultCallback);
RequestedOrientation = Android.Content.PM.ScreenOrientation.Portrait;
base.OnCreate(bundle);
SetContentView(Resource.Layout.Photo);
PictureTaken = false;
MySubjectInfo = new CurrentSubjectInfo("", "", "", "", "");
// retrieve subject information from previous activity
MySubjectInfo = Mybundle.GetParcelable("MySubjectInfo", Java.Lang.Class.FromType(typeof(CurrentSubjectInfo))) as CurrentSubjectInfo;
ImageButton camerabutton = FindViewById<ImageButton>(Resource.Id.button1);
MyImageView = FindViewById<ImageView>(Resource.Id.imageView1);
camerabutton.Click += (sender, evt) =>
{
var cameraispresent = CheckCameraHardware();
if (cameraispresent)
{
try
{
// get directory where pictures are stored
App._dir = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures);
// build file name
MySubjectInfo.Name = MySubjectInfo.Name.Replace(",", "");
MySubjectInfo.Name = MySubjectInfo.Name.Replace(" ", "");
MySubjectInfo.Name = MySubjectInfo.Name.Replace(".", "");
var filename = MySubjectInfo.Name + ".jpg";
App._file = new File(App._dir, String.Format(filename, Guid.NewGuid()));
uri = FileProvider.GetUriForFile(this, this.ApplicationContext.PackageName + ".provider",App._file);
// launch camera activity
_activityResultLauncher.Launch(uri);
}
catch (Exception e)
{
// trap error and log it
};
}
};
}
}
Boolean CheckCameraHardware()
{
Android.Content.PM.PackageManager pm = PackageManager;
if (pm.HasSystemFeature(Android.Content.PM.PackageManager.FeatureCamera))
{
// this device has a camera
return true;
}
else
{
// no camera on this device
return false;
}
}
private void ActivityResultCallback_ActivityResultCalled(object sender, ActivityResult result)
{
// result is always null, so I don't check it
try
{
// Because the resulting bitmap is rotated and too large, I set original orientation and resize
// suffice it to say it works perfectly so I won't post the code here
int height = 260;
int width = 200;
App.bitmap = App._file.Path.LoadAndResizeBitmap(width, height);
Bitmap bitmap = App.bitmap;
var filePath = App._file.AbsolutePath;
// save the resized bitmap, overwriting original file
var stream = new System.IO.FileStream(filePath, System.IO.FileMode.Create);
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
stream.Close();
// set the imageview to the resulting bitmap
MyImageView.SetImageBitmap (App.bitmap);
// cleanup
bitmap = null;
App.bitmap = null;
PictureTaken = true;
}
catch (Exception ex)
{
PictureTaken = false;
// trap and log error
}
}
}
这是ActivityResultCallback
类:
public class ActivityResultCallback : Java.Lang.Object, IActivityResultCallback
{
public EventHandler<ActivityResult> OnActivityResultCalled;
public void OnActivityResult(Java.Lang.Object result)
{
ActivityResult activityResult = result as ActivityResult;
OnActivityResultCalled?.Invoke(this, activityResult);
}
}
如上所述,除了Java.Lang.Object result
始终为空之外,所有这些代码都完美地执行,没有任何错误。我需要知道用户何时取消摄像头活动,我会假设Java.Lang.Object result
将指示cancelled
,但我什么也得不到。我错过了什么?
1条答案
按热度按时间uplii1fm1#
好了,经过一番尝试之后,我注意到
ActivityResultCallback
类中的参数Java.Lang.Object result
可能是true
,也可能是false
,这取决于用户使用相机的方式,因此我将该类更改为:在
ActivityResultCallback_ActivityResultCalled
函数中,我将其修改为:activityResult
显然至少有两个参数,result和data。我已经有了data所需的参数,所以我将其设置为null,并根据result为true还是false将Result.Ok
或Result.Cancelled
转换为int。我仍然不完全理解如何使用新的ActivityForResult
API,但这对我很有效,我正在使用它。