首页 > 解决方案 > ZXingScannerFragment.StartScanning() 首次应用启动时显示黑屏

问题描述

我有以下内容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没有在第一个中启动相机。权限很好,我已经检查过了。

谁能帮我吗?

标签: c#androidxamarinxamarin.androidzxing

解决方案


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

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

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

该问题的完整解决方案是使用第三方代码来维护授予权限的过程,而不是内置 ZXing。我检查了 James Montemagno 的PermissionsPlugin ,它运行良好。但它需要做太多的代码更改并添加额外的插件,所以我决定使用简单的解决方案。也许它对你的情况有帮助。


推荐阅读