【问题标题】:Scanner is null and not accessible扫描仪为空且不可访问
【发布时间】:2017-10-07 01:14:05
【问题描述】:

我正在尝试在 Xamarin.Forms 中读取 QRCode。我在 XF 中有一个共享项目。我已经为 ZXing.Net 添加了 nuget 包。在 iOS 项目中一切正常。我在 Android 项目中遇到错误。我通过 Android SDK Monitor 得到的错误,它表明扫描仪存在问题并且无法访问。我猜我在 Android 端有一些设置不正确。有人在我的代码中看到任何不当之处吗?感谢您的宝贵时间。

ScanPage class:
public class ScanPage : ContentPage
{
    ZXing.Net.Mobile.Forms.ZXingScannerView zxing;
    ZXingDefaultOverlay overlay;
    bool isConnected = false;
    string basicUrl = "golfeventscores.azurewebsites.net";
    public ScanPage ()
    {

        zxing = new ZXing.Net.Mobile.Forms.ZXingScannerView
        {
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.FillAndExpand,
            AutomationId = "zxingScannerView",
        };
        zxing.OnScanResult += async (ZXing.Result result) => {
            zxing.IsAnalyzing = false;
            zxing.IsScanning = false;
            var teamToken = result.Text;
            //MessagingCenter.Send<string>(teamToken, "SelectTeamMembers");
            isConnected = await Plugin.Connectivity.CrossConnectivity.Current.IsRemoteReachable(basicUrl);
            if (isConnected)
            {
                await GetTeamData(teamToken);
            }
            else
            {
                await DisplayAlert("Connectivity", "There is a problem with internet connectivity. Please try and reload this screen.", "Ok");
            }
        };

        overlay = new ZXingDefaultOverlay
        {
            TopText = "Hold your phone up to the barcode",
            BottomText = "Scanning will happen automatically",
            ShowFlashButton = zxing.HasTorch,
            AutomationId = "zxingDefaultOverlay",
        };
        overlay.FlashButtonClicked += (sender, e) => {
            zxing.IsTorchOn = !zxing.IsTorchOn;
        };
        var grid = new Grid
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand,
        };
        grid.Children.Add(zxing);
        grid.Children.Add(overlay);

        // The root page of your application
        Content = grid;
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        zxing.IsScanning = true;
    }

    protected override void OnDisappearing()
    {
        zxing.IsScanning = false;
        base.OnDisappearing();
    }
    async System.Threading.Tasks.Task GetTeamData(string Token)
    {
        try
        {
            var scanResult = await WebServices.ws.TokenLookup(Token);
            if (scanResult.Result == true)
            {
                if (scanResult.IsScoreBoard == true)
                {
                    var uri = new System.Uri(scanResult.ScoreboardUrl);
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Device.OpenUri(uri);
                        Navigation.PopToRootAsync();
                    });
                }
                if (scanResult.IsCharity == true)
                {
                    if (scanResult.TeamPlayers.Count > 0)
                    {
                        var player = scanResult.TeamPlayers.First();
                        var playerId = player.PlayerTeamId;
                        var urlResult = await WebServices.ws.ServerUrl(Token, playerId);

                        if (urlResult.ValidRequest && (!String.IsNullOrEmpty(urlResult.Url)))
                        {
                            var uri = new System.Uri(urlResult.Url);
                            Device.OpenUri(uri);
                            await Navigation.PopToRootAsync();
                        }
                    }
                    else{
                        await DisplayAlert("Scanning", "There was a problem downloading the Charity Team Info.", "OK");
                    }
                }
                else
                {
                    if (scanResult.IsLargeGame != true)
                    {
                        var select = new Pages.SelectTeamMembers(Token);
                        await Navigation.PushAsync(select);
                    }
                    else
                    {
                        await DisplayAlert("Large Game", "Don't have the large team game setup with scanning.", "Ok");
                    }
                }
            }
            else
            {
                await DisplayAlert("Server Problem", "There was some type of server error. Please try again or call Wally.", "Ok");
            }
        }
        catch(System.Exception sysExc)
        {
            //nothing seems to be caught
        }
    }
}

MainActivity.cs contents:
[Activity (Label = "TD Scan", Icon = "@drawable/icon", Theme="@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate (Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar; 

        base.OnCreate (bundle);
        global::Xamarin.Forms.Forms.Init (this, bundle);
        ZXing.Net.Mobile.Forms.Android.Platform.Init();
        LoadApplication (new GolfGameScanApp.App ());
    }

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
    {
        ZXing.Net.Mobile.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

【问题讨论】:

    标签: xamarin xamarin.forms zxing zxing.net


    【解决方案1】:

    你都在 Android Project 中定义了吗?

    Xamarin 表单

    对于 Xamarin Forms,需要进行更多设置。您需要在特定平台的应用项目中初始化每个平台上的库。

    安卓

    在 Android 上,在主 Activity 的 OnCreate (..) 实现中,调用:

    ZXing.Net.Mobile.Forms.Android.Platform.Init();
    

    ZXing.Net.Mobile for Xamarin.Forms 还为您处理新的 Android 权限请求模型,但您还需要将以下覆盖实现添加到您的主 Activity:

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
    {
        global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult (requestCode, permissions, grantResults);           
    }
    

    相机权限应该自动包含在 AndroidManifest.xml 中,但是如果您想使用 Torch API,您仍然需要自己添加手电筒权限。您可以使用以下程序集级别属性来执行此操作:

    [assembly: UsesPermission (Android.Manifest.Permission.Flashlight)]
    

    【讨论】:

    • 谢谢。是的,所有这些都已经完成了。我把它放在上面我从项目中粘贴出来的示例代码中。 :-) 请保持可能出现的问题!也感觉我可能在错误的线程上做某事,但找不到它。我以前到处都有一堆 Device.BeginInvokeOnMainThread 调用,但它对我没有任何作用。
    • 所以,我回去研究这个。看来,如果您尝试在此 OnScanResult 方法中进行一些处理工作,点击 UI,无论如何,Android 上会发生导致组件崩溃的事情。我返回并通过 MessageCenter 实现了一些消息传递以开始处理,这似乎使事情按预期工作。我昨天在 IM 上和 Redth 谈了一点,但他正在休假。等他回来我看看他是否知道什么。在那之前,我现在似乎还在工作。
    • 感谢您的想法@Alessandro。他们确实有帮助。 :-)
    猜你喜欢
    • 2014-08-27
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多