无法检测Android条形码扫描程序输入的关键事件,JavaScript

时间:2016-10-31 10:00:30

标签: javascript android jquery css barcode-scanner

范围

我正在尝试使用JavaScript在简单的Web应用程序中检测集成到手持Android设备中的条形码扫描仪的字符输入。由于大多数条形码扫描仪的行为类似于键盘楔形,因此我使用检测事件keypress和/或keyup来解释和处理字符输入。

我不希望字符输入填充文本输入,因此我已将事件处理程序分配给document,但是,我知道我也可以将其分配给window

示例代码

我完成任务的示例代码如下所示; 此示例不区分键盘输入和扫描仪输入,但我已经解决了这个问题。

var barcodeString = "";

$(document).keypress(function (event) {
    // If character is carriage-return prevent submit.
    if (event.which === 13) {
        event.preventDefault();
    }
    // Append other characters to barcodeString.
    barcodeString += event.key;
});

问题

我的问题是许多设备根本不返回任何可读字符。当我使用event.keyCode监控字符代码时,我收到两个代码:229和13.本文W3 keyCode in key events和此StackOverflow应答Is it OK to ignore keydown events with keyCode = 229?概述了229代码意味着输入监视器正忙。我只能假设这是因为:

  • 条形码扫描器在插入字符时锁定输入监视器。
  • 字符输入的速度导致输入监视器变得太忙而无法检测字符输入。

有趣的是,如果我在将文本扫描到文本输入时检测到event.keyCode,则会检测到两个字符代码:229和13,然后 然后将文本插入到文本输入中文字输入。

设备

我试图实现的设备是由Handheld Group制造的Nautiz X2。而另一款Android设备,我无法识别其品牌,但使用不同的条码扫描软件似乎更为通用。

变通方法

1

Handheld Group确实提供了一个JavaScript API,用于与手持式扫描仪进行交互。它的工作方式是为名为Kiosk Browser的自定义浏览器提供APK,并实现对扫描程序特定的JavaScript的解释。文档可以在这里找到(它非常短而且不长读):JavaScript Scanner Interface

2

更通用的Android设备能够“减慢”扫描仪上的字符输入,使扫描仪与第三方应用程序更兼容。看,切换此选项可以让我检测字符输入。虽然event.key总是返回代码229(这次是从一个不可读的字符开始),但String.fromCharCode(event.which)将在某种程度上解决问题(它不处理特殊字符)。 Nautiz X2无法在软件设置中“减慢”输入。

3

我考虑过的替代解决方法是将文本输入放在具有样式display: none的网页上以隐藏它并使用JavaScript来持续关注输入。我可以尝试来监控onChange并处理字符输入。我真的想避免这种做法。

摘要

我提出的解决方法看起来很糟糕,第一个不是设备独立的。我想知道是否有更好的地方从条形码扫描仪“转储”文本输入,所以我可以在我的应用程序中处理它?或者,是否有可以监视的事件来检测字符输入?

1 个答案:

答案 0 :(得分:0)

我知道这已经很晚了,但是我在包括Zebra TC20和Chainway C71在内的一系列设备中都面临着类似的问题。经过大量搜索之后,我发现了Bob Jase的这个惊人的Codepen示例。他已经在代码中记录了他的解决方案,但出于存档目的,我将在此处重新发布。 link to his CodePen

他的解决方案使用隐藏元素将焦点从可见元素更改为焦点,从而隐藏了柔软的Android键盘。

// whenever the visible field gets focused
$("#visibleField").bind("focus", function(e) {
  // silently shift the focus to the hidden select box
  $("#hiddenField").focus();
  $("#cursorMeasuringDiv").css("font", $("#visibleField").css("font"));
});

// whenever the user types on his keyboard in the select box
// which is natively supported for jumping to an <option>
$("#hiddenField").bind("keypress",function(e) {
  // get the current value of the readonly field
  var currentValue = $("#visibleField").val();
  
  // and append the key the user pressed into that field
  $("#visibleField").val(currentValue + e.key);
  $("#cursorMeasuringDiv").text(currentValue + e.key);
  
  // measure the width of the cursor offset
  var offset = 3;
  var textWidth = $("#cursorMeasuringDiv").width();
  $("#hiddenField").css("marginLeft",Math.min(offset+textWidth,$("#visibleField").width()));
  
});
#hiddenField {
  height:17px; 
  width:1px;
  position:absolute;
  margin-left:3px;
  margin-top:2px;
  border:none;
  border-width:0px 0px 0px 1px;
}

#cursorMeasuringDiv {
  position:absolute;
  visibility:hidden;
  margin:0px;
  padding:0px;
}

#hiddenField:focus {
  border:1px solid gray;  
  border-width:0px 0px 0px 1px;
  outline:none;
  animation-name: cursor;
  animation-duration: 1s;
  animation-iteration-count: infinite;
}

@keyframes cursor {
    from {opacity:0;}
    to {opacity:1;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click on the field and type (it should work even though the field isn't really focused): 
<p />

<!-- must be a select box with no children to suppress the keyboard -->
input: <select id="hiddenField" /> 
<span id="fakecursor" />

<input type="text" readonly="readonly" id="visibleField" />
<div id="cursorMeasuringDiv" />

我希望这会有所帮助。再次感谢Bob的解决!