web-dev-qa-db-ja.com

Webページ内でのzxingバーコードスキャナーの使用

Webページからzxingバーコードスキャナーを使用する方法の実用的な例はありますか?

このドキュメントを参照してください: https://github.com/zxing/zxing/wiki/Scanning-From-Web-Pages

次のテストコードは機能しないはずですか?

function Test1()
{
        $.ajax(
        {
        url: "zxing://scan/?ret=http%3A%2F%2Ffoo.com%2Fproducts%2F%7BCODE%7D%2Fdescription&SCAN_FORMATS=UPC_A,EAN_13",
        success:function()
                {
            alert("success");
        },
        error:function()
                {
            alert("error");
        }
    });
}
        
function Test2()
{
        $.ajax(
        {
        url: "http://zxing.appspot.com/scan?ret=http%3A%2F%2Ffoo.com%2Fproducts%2F%7BCODE%7D%2Fdescription&SCAN_FORMATS=UPC_A,EAN_13",
        success:function()
                {
            alert("success");
        },
        error:function()
                {
            alert("error");
        }
    });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<button id="button1" onClick="Test1();">Test 1</button>
<br>
<br>
<button id="button2" onClick="Test2();">Test 2</button>

Android 4.4.2 Samsung GalaxyTabProとSamsungGalaxy S4で「エラー」が発生し続けます。ストックブラウザ、Chrome、Firefox、DolphinBrowserを試しました。

http://zxing.appspot.com/scan でも、(すでにインストールされている)アプリをインストールするように常に求められるため、機能しません。

どんな助けでも大歓迎です。

11
CrazyTea

ZXingはAJAXで動作するようには設計されていません。代わりに、デフォルトのブラウザで解析されたURLを開くことで機能します。ブラウザの動作は、主にその時点からのユーザーエクスペリエンスに責任があります。

これに関して投稿されたいくつかの方法があります。残念ながら、すべてのブラウザで機能する方法は1つではありません。

一部のブラウザは、コマンドラインから開くと、URLがすでに別のタブで開かれているかどうかを確認し、開かれている場合は、新しいタブの代わりにそのタブを使用します。これにより、zxingリンクに「zxing:// scan /?ret = mytab.html#{CODE}」が含まれている場合、「onhashchange」イベントが発生します。

他のブラウザはそのようなチェックを実行しないため、複数のタブがあり、すべて同じURL(ハッシュを除く)を持ち、いずれも「hashchanged」イベントを発生させません。これらのブラウザでは、可能であれば(スキャンごとにネットワークトラフィックを防ぐために)キャッシュからページを再利用し、localStorageの値をハッシュに変更する必要があります。ブラウザが「ストレージ」イベントをリッスンできる場合は、それを使用してコードをトリガーできます。

以下のコードは、Chrome、組み込みのAndroidブラウザ、およびFirefoxで動作します。他の人と一緒に動作するかもしれませんが、私は試していません。ただし、Firefoxの注意点の1つは、about:config設定「dom.allow_scripts_to_close_windows」が「true」に設定されている場合にのみスキャナーウィンドウが閉じることです。

**これは、スキャンを許可する複数のページでより適切に機能するように編集され、コードに干渉することなく、異なるハッシュを使用できるようになりました。 ****

新しいバージョン12/19/16

<!DOCTYPE html>
<HTML>
<HEAD>
<script type="text/javascript">

    if(window.location.hash.substr(1,2) == "zx"){
        var bc = window.location.hash.substr(3);
        localStorage["barcode"] = decodeURI(window.location.hash.substr(3))
        window.close();
        self.close();
        window.location.href = "about:blank";//In case self.close isn't allowed
    }
</script>
<SCRIPT type="text/javascript" >
    var changingHash = false;
    function onbarcode(event){
        switch(event.type){
            case "hashchange":{
                if(changingHash == true){
                    return;
                }
                var hash = window.location.hash;
                if(hash.substr(0,3) == "#zx"){
                    hash = window.location.hash.substr(3);
                    changingHash = true;
                    window.location.hash = event.oldURL.split("\#")[1] || ""
                    changingHash = false;
                    processBarcode(hash);
                }

                break;
            }
            case "storage":{
                window.focus();
                if(event.key == "barcode"){
                    window.removeEventListener("storage", onbarcode, false);
                    processBarcode(event.newValue);
                }
                break;
            }
            default:{
                console.log(event)
                break;
            }
        }
    }
    window.addEventListener("hashchange", onbarcode, false);

    function getScan(){
        var href = window.location.href;
        var ptr = href.lastIndexOf("#");
        if(ptr>0){
            href = href.substr(0,ptr);
        }
        window.addEventListener("storage", onbarcode, false);
        setTimeout('window.removeEventListener("storage", onbarcode, false)', 15000);
        localStorage.removeItem("barcode");
        //window.open  (href + "#zx" + new Date().toString());

        if(navigator.userAgent.match(/Firefox/i)){
            //Used for Firefox. If Chrome uses this, it raises the "hashchanged" event only.
            window.location.href =  ("zxing://scan/?ret=" + encodeURIComponent(href + "#zx{CODE}"));
        }else{
            //Used for Chrome. If Firefox uses this, it leaves the scan window open.
            window.open   ("zxing://scan/?ret=" + encodeURIComponent(href + "#zx{CODE}"));
        }
    }

    function processBarcode(bc){
        document.getElementById("scans").innerHTML += "<div>" + bc + "</div>";
        //put your code in place of the line above.
    }

</SCRIPT>
<META name="viewport" content="width=device-width, initial-scale=1" />
</HEAD>
<BODY>
<INPUT id=barcode type=text >
<INPUT style="width:100px;height:100px" type=button value="Scan" onclick="getScan();">
<div id="scans"></div>
</BODY>
</HTML>

スクリプトの最上位ブロックのJSインクルードファイルを作成し、スキャン機能が必要なすべてのページにインクルードすることができます。

次に、ドキュメントの本文で、getZxing()を呼び出すイベントをどこかに設定できます。このイベントは、ページに書き込んだprocessBarcode(barcode)を呼び出します。たとえば、簡単なものが含まれています。

サイドノート:ページから初めてzxingを実行すると、デフォルトのアプリを選択するように求められます。ページを実行しているのと同じブラウザを選択していることを確認してください。さらに、以前にzxingのデフォルトのブラウザを選択していて、zxingに使用するブラウザを変更したい場合は、他のブラウザからデフォルトをクリアする必要があります。

@ sean-owenのハードワークと素晴らしい製品に感謝します。

2016年12月19日更新

わかりました。FirefoxとChromeでうまく機能するもう少し堅牢なバージョンを作成しました。私が発見したいくつかのこと:

スキャナーがChromeを自動的に開くように設定されていない場合、ChromeはStorageイベントを使用し、デフォルトになった後にHashイベントを使用します。

FirefoxはHashイベントを使用しませんが、window.location.hrefでスキャナーを呼び出さない限り、追加のウィンドウを開きます(ありがとう、@ Roland)

他にもいくつかの異常がありますが、取引を妨げるものはありません。

コードがスキャナーハッシュと通常のハッシュを区別できるように、ハッシュに「zx」プレフィックスを残しました。そのままにしておくと、processBarcode関数で気付かず、非zxハッシュが期待どおりに動作します。

20
alfadog67