JavaScript bridge API
QR and barcode scanner
Google’s scanner screen from one promise, AppMint.scanCode() - no camera permission, and the parsed URL, Wi-Fi, phone or contact for common QR codes.
AppMint.scanCode helper#
AppMint.scanCode(options)
Example
Opens Google's QR code and barcode scanner screen and gives you what was scanned. One call - no camera permission, no <video>, no UI of your own.
Returns: a Promise that always resolves: {ok: true, value, displayValue, format, type, …} or {ok: false, code, message}. Needs: nothing to switch on. The phone needs Google Play services.
Any code:
async function scan() {
if (!(window.AppMint && AppMint.scanCode)) { alert('Open this page in the app to scan'); return; }
var r = await AppMint.scanCode();
if (!r.ok) {
if (r.code === 'cancelled') return; // the user closed the scanner
if (r.code === 'unavailable') alert('The scanner is not available on this phone');
else if (r.code === 'busy') alert('A scan is already open');
else alert('Scan failed: ' + r.message); // 'failed'
return;
}
console.log(r.value, r.format, r.type); // "TICKET-4821", "qr_code", "text"
}Only some formats, and a "type it in" option for damaged labels:
var r = await AppMint.scanCode({
formats: ['ean_13', 'ean_8', 'upc_a', 'upc_e'], // shop barcodes
manualInput: true, // lets the user type the code
autoZoom: true // default true
});
if (r.ok) lookUpProduct(r.value);Ready-made parts - only the part that matches r.type is present:
var r = await AppMint.scanCode({ formats: ['qr_code'] });
if (r.ok) {
if (r.type === 'url') openLink(r.url.url); // url: { url, title }
if (r.type === 'wifi') showWifi(r.wifi.ssid, r.wifi.password, r.wifi.encryption); // 'wpa'|'wep'|'open'
if (r.type === 'phone') callNumber(r.phone); // a string
if (r.type === 'email') writeMail(r.email.address, r.email.subject, r.email.body);
if (r.type === 'sms') writeSms(r.sms.phoneNumber, r.sms.message);
if (r.type === 'geo') showMap(r.geo.lat, r.geo.lng);
if (r.type === 'contact') addContact(r.contact.name, r.contact.organization, r.contact.phones, r.contact.emails);
}Notes: Format names: qr_code, aztec, codabar, code_39, code_93, code_128, data_matrix, ean_8, ean_13, itf, pdf417, upc_a, upc_e (unknown names are ignored; none = all formats). type is one of url, wifi, text, phone, email, sms, geo, contact, calendar, isbn, product, driver_license, unknown. Error codes: cancelled (closed, including with Back), unavailable (no Play services, or the scanner could not be downloaded), busy (a scan is already open), failed. The first scan on a phone can take a few seconds while Play services downloads the scanner. AI-built apps use scanCode() from @/lib/appmintNative, which also scans on the web.
__ocrAvailable bridge#
window.WebToApk.__ocrAvailable(): Boolean
TextDetector / recognizeText(): Google Play services is here (the OCR module's home).
Example
Internal transport behind TextDetector: whether Google Play services (where the recognizer comes from) is on this phone. Pages use the standard API; never call this directly - the __ methods may change without notice.
Returns: true or false. When false, TextDetector is not installed at all. Needs: nothing.
Use the public API:
if ('TextDetector' in window) scanButton.hidden = false;Notes: Implemented in the app shell (TextRecognitionBridge.kt).
__ocrRecognize bridge#
window.WebToApk.__ocrRecognize(requestId: String, base64: String)
Recognises the text in [base64] (PNG/JPEG); the answer arrives as `appmint:ocr {requestId, blocks|error}`.
Example
Internal transport behind TextDetector.detect(): recognises the text in a PNG/JPEG. Pages use the standard API; never call this directly - the __ methods may change without notice.
Returns: nothing; the answer arrives as the appmint:ocr event {requestId, blocks:[{text, box, corners, lines}]} or {requestId, error} (unavailable, bad-image, failed: …). Needs: nothing.
Use the public API:
const lines = await new TextDetector().detect(document.getElementById('receipt'));
console.log(lines.map((l) => l.rawValue));Notes: Implemented in the app shell (TextRecognitionBridge.kt).
scanCode bridge#
window.WebToApk.scanCode(optionsJson: String, callbackId: String)
Opens Google's code scanner; [optionsJson] `{formats?, autoZoom?, manualInput?}`. Resolves the AppMint.scanCode promise [callbackId].
Example
Internal plumbing behind AppMint.scanCode() - pages use that Promise helper, which opens Google's QR/barcode scanner and resolves with the result.
Returns: nothing directly; the result resolves the AppMint.scanCode() promise. Needs: nothing to switch on (no camera permission). The phone needs Google Play services.
The public API:
async function scanTicket() {
if (!(window.AppMint && AppMint.scanCode)) { alert('Open this page in the app to scan'); return; }
var r = await AppMint.scanCode({ formats: ['qr_code'] });
if (r.ok) checkTicket(r.value); // r.format, r.type, r.displayValue…
else if (r.code !== 'cancelled') alert('Scan failed (' + r.code + ')');
}Notes: The raw method takes optionsJson ({formats?, autoZoom?, manualInput?} as a JSON string) and a callbackId; the answer is delivered to the helper's internal reply table, so a page calling it directly gets no answer. Only one scan runs at a time - a second call answers code: 'busy'. See AppMint.scanCode for every result field and error code.