繁体   English   中英

ZXingScannerFragment.StartScanning()在首次启动应用程序时显示黑屏

[英]ZXingScannerFragment.StartScanning() shows black screen at first app launch

我有以下Fragment ,可通过单击选项卡进行调用:

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 fragment

public class CustomZXingFragment : ZXingScannerFragment
{
    public override View OnCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle)
    {
        var view = base.OnCreateView(layoutInflater, viewGroup, bundle);
        var activity = (MainActivity)Model.Model.MainActivityContext;
        return view;
    }

    public void DoneScanning(Result scannedText)
    {
        // ...
    }
}

由于某种原因,只有在您第一次启动该应用程序时,相机才无法启动。 它显示默认的红色水平线,但背景仅是黑色。 如果我重新启动应用程序,它就可以正常工作。 我从第一次启动中获取了调试输出(显示黑色背景):

02-03 16:29:01.627 D/ZXing.Net.Mobile(21530): ZXingScannerFragment->OnResume exit
02-03 16:29:01.635 D/ViewRootImpl@d630583[MainActivity](21530): Relayout returned: oldFrame=[0,0][720,1280] newFrame=[0,0][720,1280] result=0x1 surface={isValid=true -885530624} surfaceGenerationChanged=false
02-03 16:29:01.652 D/SurfaceView(21530): Relayout returned: oldFrame=[0,0][0,0] newFrame=[0,48][720,1280] result=0x7 surface={Surface(name=null)/@0x8798822 isValid=true -918034432}
02-03 16:29:01.673 D/SurfaceView(21530): Relayout returned: oldFrame=[0,48][720,1280] newFrame=[0,48][720,1280] result=0x1 surface={Surface(name=null)/@0x8798822 isValid=true -925298688}

和第二个开始(效果很好):

02-03 16:30:38.284 D/ZXing.Net.Mobile(22786): ZXingScannerFragment->OnResume exit
02-03 16:30:38.293 D/ViewRootImpl@431432[MainActivity](22786): Relayout returned: oldFrame=[0,0][720,1280] newFrame=[0,0][720,1280] result=0x1 surface={isValid=true -878399488} surfaceGenerationChanged=false
02-03 16:30:38.316 D/SurfaceView(22786): Relayout returned: oldFrame=[0,0][0,0] newFrame=[0,48][720,1280] result=0x7 surface={Surface(name=null)/@0x393638a isValid=true -914219008}
02-03 16:30:38.316 D/ZXing.Net.Mobile(22786): Checking android.permission.CAMERA...
02-03 16:30:38.319 D/ZXing.Net.Mobile(22786): Checking Number of cameras...
02-03 16:30:38.320 I/ServiceManager(22786): Waiting for service media.camera...
02-03 16:30:38.324 I/art     (22786): Do partial code cache collection, code=23KB, data=28KB
02-03 16:30:38.324 I/art     (22786): After code cache collection, code=19KB, data=24KB
02-03 16:30:38.324 I/art     (22786): Increasing code cache capacity to 128KB
02-03 16:30:39.322 D/ZXing.Net.Mobile(22786): Found 2 cameras...
02-03 16:30:39.325 D/ZXing.Net.Mobile(22786): Found Back Camera, opening...
02-03 16:30:39.404 D/ZXing.Net.Mobile(22786): Selected Resolution: 960x720
02-03 16:30:39.412 D/ZXing.Net.Mobile(22786): Changing Camera Orientation to: 90
02-03 16:30:39.822 D/ZXing.Net.Mobile(22786): Selected Resolution: 960x720
02-03 16:30:39.831 D/ZXing.Net.Mobile(22786): Changing Camera Orientation to: 90
02-03 16:30:39.846 I/Choreographer(22786): Skipped 92 frames!  The application may be doing too much work on its main thread.
02-03 16:30:39.856 D/SurfaceView(22786): Relayout returned: oldFrame=[0,48][720,1280] newFrame=[0,48][720,1280] result=0x1 surface={Surface(name=null)/@0x393638a isValid=true -890101760}
02-03 16:30:42.144 I/art     (22786): Starting a blocking GC Explicit
02-03 16:30:42.150 D/Mono    (22786): GC_BRIDGE waiting for bridge processing to finish
02-03 16:30:42.198 I/art     (22786): Explicit concurrent mark sweep GC freed 4669(256KB) AllocSpace objects, 5(4MB) LOS objects, 39% free, 8MB/14MB, paused 532us total 54.160ms
02-03 16:30:42.201 D/Mono    (22786): GC_TAR_BRIDGE bridges 319 objects 388 opaque 66 colors 322 colors-bridged 319 colors-visible 319 xref 9 cache-hit 0 cache-semihit 0 cache-miss 3 setup 0.13ms tarjan 0.34ms scc-setup 0.23ms gather-xref 0.02ms xref-setup 0.02ms cleanup 0.12ms
02-03 16:30:42.201 D/Mono    (22786): GC_BRIDGE: Complete, was running for 59.51ms
02-03 16:30:42.201 D/Mono    (22786): GC_MAJOR: (LOS overflow) time 11.64ms, stw 12.98ms los size: 3072K in use: 765K
02-03 16:30:42.201 D/Mono    (22786): GC_MAJOR_SWEEP: major size: 1312K in use: 485K

如您所见,存在差异,但是我不知道为什么ZXing没有在第一个中启动相机。 权限很好,我已经检查过了。

谁能帮我吗?

当ZXingScannerFragment在首次启动应用程序时显示黑屏时,我遇到了同样的问题。 经过调查,我找到了补救办法。 我只是替换.Commit(); 使用.CommitAllowingStateLoss(); 在创建ZxingFragment的方法中。

SupportFragmentManager.BeginTransaction()
    .Replace(Resource.Id.fragment_container, _zXingScannerFragment)
    .CommitAllowingStateLoss(); 

我发现有关相机授予权限的@pnavk假设是正确的。 即使在使用await PermissionsHandler.RequestPermissionsAsync(this); PermissionsHandler.PermissionRequestTask未成功完成。

完整的解决方案是使用第三方代码来维护授予权限的过程,而不是内置的ZXing。 我检查了James Montemagno的PermissionsPlugin ,它运行完美。 但这需要进行过多的代码更改并添加其他插件,因此我决定使用简单的解决方案。 也许对您有帮助。

因为这只是第一次发生,所以听起来像是由对RequestPermissionsAsync的调用引起的。 我假设您是第一次接受该权限,因此第二次围绕needsPermissionRequest条件解析为false并且不会调用RequestPermissionsAsync ,因此代码可以正常工作。

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

ZXing.Net.Mobile.Android.PermissionsHandler.RequestPermissionsAsync(Activity)
                .ContinueWith((b) => ShowScanFragment());

您应该awaitasync方法调用,而不要使用ContinueWith ShowScanFragment是在后台线程而不是似乎引起您问题的UI线程中调用的。

您还可以删除以下行:

var needsPermissionRequest = ZXing.Net.Mobile.Android.PermissionsHandler.NeedsPermissionRequest(Model.Model.MainActivityContext);

如果您检查了ZXing源代码,则在调用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
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM