C# ZXingScannerFragment.StartScanning()在第一次应用程序启动时显示黑屏

C# ZXingScannerFragment.StartScanning()在第一次应用程序启动时显示黑屏,c#,android,xamarin,xamarin.android,zxing,C#,Android,Xamarin,Xamarin.android,Zxing,我有以下片段,它是通过单击选项卡调用的: public class HomeFragment : Fragment { private CustomZXingFragment scanFragment; public override void OnStart() => base.OnStart(); public override void OnCreate(Bundle savedInstanceState) => base.OnCreate(save

我有以下
片段
,它是通过单击选项卡调用的:

public class HomeFragment : Fragment
{
    private CustomZXingFragment scanFragment;

    public override void OnStart() => base.OnStart();

    public override void OnCreate(Bundle savedInstanceState) => base.OnCreate(savedInstanceState);

    public override void OnResume()
    {
        base.OnResume();

        var needsPermissionRequest = ZXing.Net.Mobile.Android.PermissionsHandler.NeedsPermissionRequest(Model.Model.MainActivityContext);
        if (needsPermissionRequest)
            ZXing.Net.Mobile.Android.PermissionsHandler.RequestPermissionsAsync(Activity)
                .ContinueWith((b) => ShowScanFragment());
        else
            ShowScanFragment();
    }

    public override void OnViewCreated(View view, Bundle savedInstanceState) => base.OnViewCreated(view, savedInstanceState);

    private void ShowScanFragment()
    {
        MobileBarcodeScanner.Initialize(Activity.Application);

        if (scanFragment == null)
        {
            scanFragment = new CustomZXingFragment();
            FragmentManager.BeginTransaction().Replace(Resource.Id.container, scanFragment).Commit();
        }

        Scan();
    }

    private void Scan()
    {
        var opts = new MobileBarcodeScanningOptions
        {

            PossibleFormats = new List<BarcodeFormat> {
                BarcodeFormat.QR_CODE,
            },
            UseNativeScanning = true,
            TryHarder = true,
        };

        scanFragment.StartScanning(scanFragment.DoneScanning, opts);
    }
出于某种原因,只有在你第一次启动应用程序时,相机才不会启动。它显示默认的红色水平线,但背景完全是黑色的。如果我重新启动应用程序,它就可以正常工作。我抓取了第一次启动时的调试输出(显示黑色背景):

第二次启动(效果良好):

正如你所看到的,这是一个矛盾,但我不知道为什么
ZXing
没有在第一次启动相机。权限很好,我已经检查过了


有人能帮我吗?

因为这只是第一次发生,所以听起来好像是调用
RequestPermissionsAsync
引起的。我假设您第一次接受许可,因此第二次在
needsPermissionRequest
条件下解析为
false
,并且
RequestPermissionsAsync
未被调用,因此代码正常工作

您应该对代码进行一些修改:

ZXing.Net.Mobile.Android.PermissionsHandler.RequestPermissionsAsync(Activity)
                .ContinueWith((b) => ShowScanFragment());
您应该
wait
async
方法调用,而不是使用
ContinueWith
。ShowScanFragment正在一个而不是UI线程中调用,该线程似乎导致了您的问题

您还可以删除以下行:

var needsPermissionRequest = ZXing.Net.Mobile.Android.PermissionsHandler.NeedsPermissionRequest(Model.Model.MainActivityContext);
如果您检查了,则在您调用
RequestPermissionsAsync
时,此检查已经为您完成,因此您无需自己执行

尝试修改您的
OnResume
方法,如下所示:

public override async void OnResume()
{
    base.OnResume();

    var permissionGranted = await ZXing.Net.Mobile.Android.PermissionsHandler.RequestPermissionsAsync(Activity);
    if(permissionGranted) {
        ShowScanFragment();
    }else{
        //handle permission denied
    }
}

当ZXingScannerFragment在第一次应用发布时显示黑屏时,我也遇到了同样的问题。经过调查,我找到了补救办法。我刚刚替换了
.Commit()
.CommitAllowingStateLoss()一起使用在创建ZxingFragment的方法中

SupportFragmentManager.BeginTransaction()
    .Replace(Resource.Id.fragment_container, _zXingScannerFragment)
    .CommitAllowingStateLoss(); 
我发现@pnavk关于相机许可的假设是正确的。即使在使用
wait PermissionsHandler.RequestPermissionsAsync之后(这一点)PermissionsHandler.PermissionRequestTask未成功完成


该问题的完整解决方案是使用第三方代码来维护授予权限的过程,而不是ZXing内置。我看过詹姆斯·蒙特马诺的作品,效果很好。但它需要做太多的代码更改和添加额外的插件,所以我决定使用简单的解决方案。也许对你有帮助

谢谢你的帮助。但是它不起作用。看起来您的权限检查是正确的,除非有必要,否则不会提示。但很显然,这并没有改变什么。ShowScanFragment()仍像普通一样被调用,但没有摄影机。重新启动应用程序可以解决这个问题。@ViggoLundén请尝试在ShowScanFragment上设置断点,以确保它不会被调用两次。我知道Android上的OnResume在权限提示被取消后再次被调用。这可能是导致问题的原因。我对权限进行了一点实验,因此我将权限请求移动到另一个片段,并将
ShowScanFragment()
移动到
OnViewCreated()
。行为保持不变。我忍不住觉得这与权限无关。这对讨论很有帮助。谢谢
var needsPermissionRequest = ZXing.Net.Mobile.Android.PermissionsHandler.NeedsPermissionRequest(Model.Model.MainActivityContext);
public override async void OnResume()
{
    base.OnResume();

    var permissionGranted = await ZXing.Net.Mobile.Android.PermissionsHandler.RequestPermissionsAsync(Activity);
    if(permissionGranted) {
        ShowScanFragment();
    }else{
        //handle permission denied
    }
}
SupportFragmentManager.BeginTransaction()
    .Replace(Resource.Id.fragment_container, _zXingScannerFragment)
    .CommitAllowingStateLoss();