You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何在纯Xamarin Android项目中读取二维码/条形码?

在纯Xamarin Android中实现二维码/条形码扫描

一、安装必要的NuGet包

安装以下两个包:

  • ZXing.Net.Mobile
  • ZXing.Net.Mobile.Android

二、方式1:使用内置扫描Activity(快速实现,无需自定义布局)

这种方式无需自行编写axml布局,直接调用ZXing提供的现成扫描界面,能避开布局适配问题:

  1. 添加相机权限
    在AndroidManifest.xml中加入权限声明:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
  1. 动态申请权限(Android 6.0+)
    启动扫描前先检查并申请相机权限:
private async Task<bool> CheckCameraPermission()
{
    var status = await Permissions.CheckStatusAsync<Permissions.Camera>();
    if (status != PermissionStatus.Granted)
    {
        status = await Permissions.RequestAsync<Permissions.Camera>();
    }
    return status == PermissionStatus.Granted;
}
  1. 启动扫描
    在按钮点击或需要触发扫描的事件中执行:
private async void btnScan_Click(object sender, EventArgs e)
{
    if (!await CheckCameraPermission())
    {
        Toast.MakeText(this, "需要相机权限才能扫描", ToastLength.Short).Show();
        return;
    }

    var scanner = new MobileBarcodeScanner(this);
    var result = await scanner.Scan();

    if (result != null)
    {
        Toast.MakeText(this, $"扫描结果:{result.Text}", ToastLength.Long).Show();
    }
}

三、方式2:自定义扫描布局(解决axml适配问题)

如果需要自定义扫描界面,按以下步骤操作:

  1. 创建适配性布局axml
    在Resources/layout下新建ScanLayout.axml,示例布局适配不同屏幕尺寸:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 相机预览控件 -->
    <zxing.android.CameraPreview
        android:id="@+id/camera_preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- 扫描框(可替换为自定义9-Patch图片保证拉伸不变形) -->
    <ImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:layout_centerInParent="true"
        android:src="@drawable/scan_frame"
        android:background="@android:color/transparent" />

    <!-- 返回按钮 -->
    <Button
        android:id="@+id/btn_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="返回" />
</RelativeLayout>
  1. 编写扫描Activity逻辑
    新建ScanActivity.cs,代码如下:
[Activity(Label = "扫描")]
public class ScanActivity : AppCompatActivity
{
    private CameraPreview _cameraPreview;
    private MobileBarcodeScanner _scanner;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.ScanLayout);

        _cameraPreview = FindViewById<CameraPreview>(Resource.Id.camera_preview);
        var btnBack = FindViewById<Button>(Resource.Id.btn_back);
        btnBack.Click += (s, e) => Finish();

        // 初始化扫描器
        _scanner = new MobileBarcodeScanner(this)
        {
            UseCustomOverlay = true,
            CustomOverlay = _cameraPreview
        };

        // 开始扫描,获取结果后返回
        _scanner.ScanContinuously((result, cancel) =>
        {
            if (result != null && !string.IsNullOrEmpty(result.Text))
            {
                Intent intent = new Intent();
                intent.PutExtra("ScanResult", result.Text);
                SetResult(Result.Ok, intent);
                Finish();
            }
        });
    }

    protected override void OnPause()
    {
        _scanner?.PauseScanning();
        base.OnPause();
    }

    protected override void OnResume()
    {
        _scanner?.ResumeScanning();
        base.OnResume();
    }

    protected override void OnDestroy()
    {
        _scanner?.StopScanning();
        base.OnDestroy();
    }
}
  1. 调用自定义扫描界面
    在主Activity中启动该Activity并接收扫描结果:
private const int ScanRequestCode = 100;

private async void btnCustomScan_Click(object sender, EventArgs e)
{
    if (!await CheckCameraPermission())
    {
        Toast.MakeText(this, "需要相机权限才能扫描", ToastLength.Short).Show();
        return;
    }

    StartActivityForResult(typeof(ScanActivity), ScanRequestCode);
}

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    if (requestCode == ScanRequestCode && resultCode == Result.Ok)
    {
        var scanResult = data.GetStringExtra("ScanResult");
        Toast.MakeText(this, $"自定义扫描结果:{scanResult}", ToastLength.Long).Show();
    }
}

四、常见适配问题解决

  • 布局适配:尽量使用match_parent、wrap_content和dp单位,避免固定像素值;扫描框使用9-Patch图片,保证拉伸时边框不变形。
  • 相机启动失败:确认权限申请成功,设备相机功能正常;Android 10+需注意系统隐私权限设置。

内容的提问来源于stack exchange,提问作者Samara Bravo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 14:06:29