本文へスキップ
Unveilydocs

QR・バーコードスキャナー

QR コードとバーコードをスキャンする

概要

カメラを開いて QR コードまたはバーコードをスキャンし、結果を返します。Android と iOS は同じ JS API と同じレスポンス形式を使用します。

機能AndroidiOS
QR コードスキャン✓(Android 7.0+)
バーコードスキャン✓(Android 7.0+)

対応プラン: Basic 以上(ライセンス機能 qr が必要)

事前準備

QR スキャンはカメラ権限を使用します。対象プラットフォームに合わせて権限を設定してください。

Android

AndroidManifest.xml ではカメラ権限がコメントアウトされた状態で配布されます。QR スキャンを使用するにはコメントを解除してください。

<uses-permission android:name="android.permission.CAMERA" />

iOS

Info.plist にカメラ使用の説明を追加する必要があります。

<key>NSCameraUsageDescription</key>
<string>QR コードおよびバーコードのスキャンにカメラへのアクセスが必要です。</string>

使い方

unveilyBridge.qr.scan(cb) を呼び出すとスキャナーが開きます。cb は結果を受け取るコールバック関数名の文字列です。省略するとデフォルトの 'onQRResult' が使用されます。

// コールバック名を明示的に指定
window.unveilyBridge.qr.scan("onQRResult");

// またはデフォルトのコールバック(onQRResult)を使用
window.unveilyBridge.qr.scan();

function onQRResult(result) {
  if (result.cancelled) {
    return;                          // ユーザーがスキャナーを閉じた
  }
  if (result.error) {
    console.error("スキャン失敗:", result.error);  // エラーまたはプラン未対応
    return;
  }

  console.log("スキャン内容:", result.text);   // スキャンされた文字列
  console.log("フォーマット:", result.format);  // 例: "QR_CODE", "EAN_13"
  console.log("タイプ:", result.type);          // コンテンツタイプ(例: "URL", "TEXT")
}

結果はすでにパースされた JS オブジェクトとして渡されます。JSON.parse() を呼び出す必要はありません。

レスポンスの構造

コールバックは次の 3 つの形式のいずれかのオブジェクトを受け取ります。

{ "text": "https://example.com", "format": "QR_CODE", "type": "URL" }
{ "cancelled": true }
{ "error": "..." }
フィールド説明
textスキャンされた文字列(成功時)
formatバーコードのシンボル体系 — QR_CODE, EAN_13, EAN_8, CODE_128, CODE_39, ITF, DATA_MATRIX, PDF_417, AZTEC など
typeコンテンツタイプの分類(例: URL, TEXT
cancelledユーザーがスキャナーを閉じると true
errorエラー発生時、またはプラン/機能が未対応の場合のエラーメッセージ

エラー処理は別の onError コールバックではなく、結果オブジェクトの cancelled / error フィールドで行います。コールバックは 1 つだけです。


実践例

QR コードが URL であればページに移動し、それ以外はサーバーに送るパターンです。

document.getElementById('scan-btn').addEventListener('click', () => {
  window.unveilyBridge.qr.scan("onScanComplete");
});

function onScanComplete(result) {
  if (result.cancelled) return;
  if (result.error) {
    alert('スキャンに失敗しました。もう一度お試しください。');
    return;
  }

  const text = result.text;
  if (text.startsWith('http')) {
    window.location.href = text;
  } else {
    sendToServer(text);
  }
}

async function sendToServer(text) {
  await fetch('/api/qr-result', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ text })
  });
}

サーバー側の処理

app.post('/api/qr-result', (req, res) => {
  const { text } = req.body;
  // バーコードの値で商品を検索するなどの処理
  const product = productService.findByBarcode(text);
  res.json({ product });
});
[HttpPost("qr-result")]
public async Task<IActionResult> ProcessQR([FromBody] QRRequest request)
{
    var product = await _productService.FindByBarcodeAsync(request.Text);
    return Ok(new { product });
}
@PostMapping("/api/qr-result")
public ResponseEntity<?> processQR(@RequestBody QRRequest request) {
    Product product = productService.findByBarcode(request.getText());
    return ResponseEntity.ok(Map.of("product", product));
}
<?php
$data = json_decode(file_get_contents('php://input'), true);
$text = $data['text'];

$stmt = $pdo->prepare('SELECT * FROM products WHERE barcode = ?');
$stmt->execute([$text]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);

header('Content-Type: application/json');
echo json_encode(['product' => $product]);
<%
Dim text
text = Request.Form("text")

Dim conn, rs, sql
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open Application("ConnectionString")

sql = "SELECT * FROM products WHERE barcode = '" & text & "'"
Set rs = conn.Execute(sql)

Response.ContentType = "application/json"
If Not rs.EOF Then
    Response.Write "{""found"": true, ""name"": """ & rs("name") & """}"
Else
    Response.Write "{""found"": false}"
End If
%>

On this page