我需要拍摄更多照片,但应用程序会在 Android 11 设备上重新启动。 Android 10 或更低版本即可。 它表现得神秘莫测。有时它发生在第三次捕获之后,有时可能发生在第七次捕获之后。
问题模拟(第二次捕获后重启):
如果我在
var photo = await MediaPicker.CapturePhotoAsync();
上放置断点
并进入下一步,什么也没有完成并且应用程序崩溃了。
这也发生在App-Essentials示例应用程序中。
编辑: 我的代码:
var file = await MediaPicker.CapturePhotoAsync();
while (LS.IsIntermediateActivity())
{ await Task.Delay(10); }
正常行为:拍摄照片,单击“确定”,下一步 - while (LS.IsIntermediateActivity()),然后在 MainActivity OnRestart 和 OnResume 中。 (LS是DependencyService)
不正确的行为:拍摄照片,单击“确定”,没有下一步 - 应用程序崩溃或重新启动并显示主页。没有例外,没有警告。
我记得我的一位同事遇到了一个非常相似的问题,媒体选择器上的这篇说明实际上解决了他们的问题
所有方法都必须在 UI 线程上调用,因为权限检查和请求由 Xamarin.Essentials 自动处理。
这很奇怪,因为他们自己的示例没有这样做:/
无论如何,请尝试一下,看看这是否可以解决您的问题:
var fileResult= await Device.InvokeOnMainThreadAsync(async () => await MediaPicker.CapturePhotoAsync());
祝你好运
如有疑问,请随时回复。
我调查了这个问题。 基本上,当从您的应用程序内使用媒体选择器打开相机时,您的应用程序会被 Android 置于后台,因为相机应用程序现在正在使用。进行一些 RAM 优化,操作系统可能会重新启动您的应用程序。在测试中,我们在 3Gb RAM 的设备上没有出现任何问题,但在 2Gb RAM 的设备上遇到了这个问题。很可能是因为内存不足。
解决方案是在离开应用程序时保存应用程序状态,并在拍照回来后重新使用该状态,以防应用程序重新启动。我们还没有找到简单的解决方案,非常欢迎提出想法......
我尝试了另一种解决方案:
public async Task<string> TakePhotoAsync()
{
waitForResult = new AsyncAutoResetEvent();
var context = Android.App.Application.Context;
var activity = Xamarin.Essentials.Platform.CurrentActivity as MainActivity;
using (var intent = new Intent(MediaStore.ActionImageCapture))
{
string timestamp = System.DateTime.Now.ToString("yyyyMMdd_HHmmss");
var file = new File(GetPictureDirPath(), "EMAphoto_" + timestamp + ".jpg");
var uri = FileProvider.GetUriForFile(context, context.ApplicationContext.PackageName + ".fileprovider", file);
intent.PutExtra(MediaStore.ExtraOutput, uri);
activity.StartActivityForResult(intent, CAMERA_REQUEST_CODE);
await waitForResult.WaitAsync().ConfigureAwait(true);
return file.Path;
}
}
而且它也崩溃了...... 愚蠢的Android 11还是我?
更新至Android 12,问题已解决...
我最近遇到了这个问题,在网上找不到解决方案,所以我在这里提供我的解决方案,希望它能帮助别人。
当前的问题是,当调用 CapturePhotoAsync 时,相机应用程序将打开,并且您的应用程序将置于后台。这使得它容易受到垃圾收集的影响,有时会导致应用程序在下次启动时重新启动。
我的解决方案: 为了在拍照时保持我们的应用程序处于活动状态,我们将在调用 CapturePhotoAsync 之前首先启动前台进程。
1.) 在 Android 项目中创建一个服务,如下所示:
[Service]
public class AndroidPhotoService : Service
2.) 在服务中,重写 OnStartCommand 并创建通知
// Create a notification and set it as a foreground service
var notification = new Notification.Builder(this)
.SetChannelId("yourChannelName")
.SetContentTitle("Whatever")
.SetContentText("Whatever")
.SetSmallIcon(Resource.Drawable.SymDefAppIcon)
.Build();
StartForeground(1, notification);
return StartCommandResult.Sticky;
3.) 确保覆盖 OnDestroy
public override void OnDestroy()
{
StopForeground(true);
base.OnDestroy();
}
4.) 在您的 MainActivity 中,设置消息订阅来捕获照片并将结果发送回您的 ViewModel
MessagingCenter.Subscribe<AddAttachmentViewModel>(this, "StartPhotoService", async (sender) =>
{
var intent = new Intent(this, typeof(AndroidPhotoService));
StartService(intent);
var photo = await MediaPicker.CapturePhotoAsync();
MessagingCenter.Send("YourMessageID", "PhotoCaptured", photo);
}
5.) 在 ViewModel 中订阅此消息并根据需要处理照片。