AtlayoInterface.setStorage(storageJson)
Store a value in persistent mini-app storage.
Parameters
| Name | Type | Description | Required |
| storageJson | String (JSON) | Object with key (String), data (Any), optional callback (String) | Yes |
Input
{
"key": "user_preference",
"data": { "theme": "dark", "language": "en" },
"callback": "onStorageSet"
}Output / Response
{
"action": "setStorage",
"key": "user_preference",
"success": true
}Example
const request = { key: "user_preference", data: { theme: "dark" }, callback: "onStorageSet" };
AtlayoInterface.setStorage(JSON.stringify(request));
function onStorageSet(response) {
console.log('Saved:', response.success);
}
AtlayoInterface.getStorage(requestJson)
Retrieve a value from persistent storage.
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | Object with key (String), optional callback (String) | Yes |
Input
{ "key": "user_preference", "callback": "onStorageGet" }Output / Response
{
"action": "getStorage",
"key": "user_preference",
"found": true,
"data": "{\"theme\":\"dark\"}"
}Example
AtlayoInterface.getStorage(JSON.stringify({ key: "user_preference" }));
function onStorageGet(response) {
if (response.found) {
const data = JSON.parse(response.data);
console.log('Theme:', data.theme);
}
}
AtlayoInterface.removeStorage(requestJson)
Remove a specific key from storage.
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | Object with key (String), optional callback | Yes |
Input
{ "key": "user_preference" }Output / Response
{
"action": "removeStorage",
"key": "user_preference",
"removed": true
}Example
AtlayoInterface.removeStorage(JSON.stringify({ key: "user_preference" }));
AtlayoInterface.clearStorage(requestJson)
Clear all data from the mini-app storage.
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | Empty object {} or object with optional callback | Yes |
Output / Response
{ "action": "clearStorage", "cleared": true }Example
AtlayoInterface.clearStorage(JSON.stringify({}));
Errors: Storage failures invoke window.onStorageError(error).
AtlayoInterface.requestPermissions(permissionsJson)
Request permission for specific user data fields. Previously granted permissions return data immediately without a dialog.
Parameters
| Name | Type | Description | Required |
| permissionsJson | String (JSON array) | Array of permission keys: given_name, family_name, phone_number, notifications, gps, token, bluetooth | Yes |
Input
["given_name", "family_name", "phone_number"]
Output / Response
{
"given_name": "John",
"family_name": "Doe",
"phone_number": "+1234567890"
}Example
const permissions = ["given_name", "family_name", "phone_number"];
AtlayoInterface.requestPermissions(JSON.stringify(permissions));
window.onPermissionsGranted = function(data) {
document.getElementById('userName').textContent =
data.given_name + ' ' + data.family_name;
const sysInfo = JSON.parse(AtlayoInterface.getSystemInfo());
if (sysInfo.token) {
fetch('/api/user-data', {
headers: { 'Authorization': 'Bearer ' + sysInfo.token }
});
}
};Auto-provided: theme_color, lang, and token are available via getSystemInfo() without requesting.
AtlayoInterface.checkPermissions(permissionsJson)
Check if specific permissions have been granted without showing a dialog.
Parameters
| Name | Type | Description | Required |
| permissionsJson | String (JSON array) | Array of permission keys | Yes |
Input
["gps", "bluetooth"]
Output / Response
{
"gps": true,
"bluetooth": false
}Example
AtlayoInterface.checkPermissions(JSON.stringify(["gps", "bluetooth"]));
window.onPermissionsChecked = function(data) {
console.log("GPS granted:", data.gps);
};
AtlayoInterface.requestAdditionalPermissions(permissionsJson)
Request new permissions to be merged with already granted ones. Shows a dialog only if there are new or previously denied permissions.
Parameters
| Name | Type | Description | Required |
| permissionsJson | String (JSON array) | Array of permission keys | Yes |
Output / Response
{
"given_name": "John",
"bluetooth": true
}Example
AtlayoInterface.requestAdditionalPermissions(JSON.stringify(["bluetooth"]));
window.onPermissionsGranted = function(data) {
// Same callback as requestPermissions
};
AtlayoInterface.setStatusBarColor(color)
Set the Android status bar color.
Parameters
| Name | Type | Description | Required |
| color | String | Hex color, e.g. "#FF0000" | Yes |
Example
AtlayoInterface.setStatusBarColor("#FF0000");
AtlayoInterface.setTopBarBackgroundColor(color)
Set the mini-app top bar background color.
Parameters
| Name | Type | Description | Required |
| color | String | Hex color | Yes |
Example
AtlayoInterface.setTopBarBackgroundColor("#3498db");
AtlayoInterface.setTopBarForegroundColor(color)
Set the mini-app top bar text/icon color.
Parameters
| Name | Type | Description | Required |
| color | String | Hex color | Yes |
Example
AtlayoInterface.setTopBarForegroundColor("#FFFFFF");
AtlayoInterface.setNavigationBarColor(color, lightNavigationBar)
Set the Android navigation bar color and icon style.
Parameters
| Name | Type | Description | Required |
| color | String | Hex color | Yes |
| lightNavigationBar | Boolean | true = light icons (dark bg), false = dark icons | Yes |
Input
AtlayoInterface.setNavigationBarColor("#000000", true)Example
AtlayoInterface.setNavigationBarColor("#000000", true);
AtlayoInterface.setOrientation(orientation)
Control the screen orientation (rotation) for the mini-app. By default, the orientation is locked to portrait.
Parameters
| Name | Type | Description | Required |
| orientation | String | "portrait", "landscape", "auto" (or "sensor"), "locked" | Yes |
Example
AtlayoInterface.setOrientation("landscape");
AtlayoInterface.getSystemInfo()
Returns comprehensive device and system information as a JSON string (synchronous).
Input
AtlayoInterface.getSystemInfo()
Output / Response
{
"brand": "samsung", "model": "SM-G991B", "platform": "android",
"screenWidth": 1080, "screenHeight": 2400, "darkMode": false,
"language": "en", "token": "", "safeArea": { "top": 28, "bottom": 0 }
}Example
const systemInfo = JSON.parse(AtlayoInterface.getSystemInfo());
document.getElementById('deviceInfo').textContent =
systemInfo.brand + ' ' + systemInfo.model;
document.getElementById('screenSize').textContent =
systemInfo.screenWidth + ' x ' + systemInfo.screenHeight;
if (systemInfo.darkMode) document.body.classList.add('dark-mode');
const safeArea = systemInfo.safeArea;
document.getElementById('content').style.paddingTop = safeArea.top + 'px';
getSystemInfo — All Properties
| Property | Type | Description |
brand | String | Device manufacturer (e.g. "samsung", "google") |
model | String | Device model name |
pixelRatio | Number | Device pixel density |
screenWidth | Number | Screen width in pixels |
screenHeight | Number | Screen height in pixels |
windowWidth | Number | Available window width in pixels |
windowHeight | Number | Available window height in pixels |
statusBarHeight | Number | Status bar height in pixels |
language | String | Current language code (e.g. "en", "cs") |
version | String | App version |
system | String | Android version (e.g. "Android 12") |
platform | String | Always "android" |
fontSizeSetting | Number | System font size setting in pixels |
SDKVersion | String | Android API level |
darkMode | Boolean | Whether dark mode is enabled |
token | String | Encrypted authentication token for the current user and mini-app |
albumAuthorized | Boolean | Photo library access permission status |
cameraAuthorized | Boolean | Camera permission status |
locationAuthorized | Boolean | Location permission status |
microphoneAuthorized | Boolean | Microphone permission status |
bluetoothEnabled | Boolean | Whether Bluetooth is enabled |
locationEnabled | Boolean | Whether GPS/location services are enabled |
wifiEnabled | Boolean | Whether WiFi is connected |
safeArea | Object | Safe area insets (for notches, etc.): left, right, top, bottom, width, height |
Availability: Use Atlayo.system for the ergonomic JavaScript API. Underlying bridge methods are also exposed on AtlayoInterface. Android only.
Atlayo.system.setWebTouchFeedback(enabled)
Disables default web-browser long-press text selection magnifiers and context menus, substituting native haptic feedback (HapticFeedbackConstants.LONG_PRESS) to give the web view a pure native app texture.
Parameters
| Name | Type | Description | Required |
| enabled | Boolean | true disables selection/context menus and enables long-press haptic feedback; false restores default browser behavior | Yes |
Output / Response
true // bridge available
false // bridge unavailable
Example
// Native-app touch feel (no magnifier / selection handles)
Atlayo.system.setWebTouchFeedback(true);
// Restore default browser long-press behavior
Atlayo.system.setWebTouchFeedback(false);
Atlayo.system.requestAppShortcut(id, label, icon, targetAction, callback)
Request pinning a dynamic launcher shortcut directly to the user's Android home screen (e.g. a "Scan & Pay" shortcut leading to a specific mini-app screen).
Parameters
| Name | Type | Description | Required |
| id | String | Unique shortcut id within your mini-app (e.g. "scan_pay"). Defaults to the mini-app ID when empty | No |
| label | String | Short label shown under the home-screen icon. Defaults to the mini-app name when empty | No |
| icon | String | Base64 PNG icon, optionally with data:image/png;base64, prefix. Defaults to the mini-app favicon when empty | No |
| targetAction | String | Deep-link action delivered via atlayo-shortcut-action event when opened from shortcut | No |
| callback | Function | String | Callback function or name (default: onShortcutResult) | No |
Input
// Defaults: mini-app id, name, and favicon
Atlayo.system.requestAppShortcut('', '', '', '/scan-pay', 'onShortcutResult')
// Custom shortcut
Atlayo.system.requestAppShortcut(
'scan_pay',
'Scan & Pay',
iconBase64Png,
'/scan-pay',
'onShortcutResult'
)Output / Response
{
"action": "requestAppShortcut",
"success": true,
"id": "scan_pay",
"shortcutId": "my_app_scan_pay"
}Example
// Use mini-app defaults for id, label, and icon
Atlayo.system.requestAppShortcut('', '', '', '/scan-pay', function(result) {
if (result.success) Atlayo.UI.toast('Shortcut requested');
});
Atlayo.system.requestAppShortcut(
'scan_pay',
'Scan & Pay',
iconBase64Png,
'/scan-pay',
function(result) {
if (result.success) Atlayo.UI.toast('Shortcut requested');
else Atlayo.UI.alert(result.error || 'Could not create shortcut');
}
);
document.addEventListener('atlayo-shortcut-action', function(e) {
if (e.detail.targetAction === '/scan-pay') openScanAndPayScreen();
});
User confirmation: The main app shows a half-screen dialog first (Cancel / Agree) with only the mini-app name and shortcut label. The mini-app URL and targetAction are never shown to the user. The callback returns cancelled: true when declined.
Atlayo.system.shareSystemSheet(title, text, url, filesJson, callback)
Opens the native OS share sheet so mini-apps can share text, URLs, images, and files with external apps (WhatsApp, Signal, Email, etc.).
Parameters
| Name | Type | Description | Required |
| title | String | Share sheet title / email subject | No |
| text | String | Plain-text body | No |
| url | String | URL appended to shared text | No |
| filesJson | String | JSON array of { name, mimeType, data } with base64 file content. Default "[]" | No |
| callback | Function | String | Callback function or name (default: onShareResult) | No |
Input
const files = JSON.stringify([{
name: 'receipt.jpg',
mimeType: 'image/jpeg',
data: receiptBase64
}]);
Atlayo.system.shareSystemSheet(
'Your receipt',
'Thanks for your order!',
'https://shop.example.com/orders/123',
files
)Output / Response
{
"action": "shareSystemSheet",
"success": true
}Example
const files = JSON.stringify([{
name: 'receipt.jpg',
mimeType: 'image/jpeg',
data: receiptBase64
}]);
Atlayo.system.shareSystemSheet(
'Your receipt',
'Thanks for your order!',
'https://shop.example.com/orders/123',
files,
function(result) {
if (!result.success) Atlayo.UI.alert(result.error || 'Share failed');
}
);
Atlayo.system.showNativeScanner(overlayConfigJson, callback)
Opens a native scanner UI backed by Google ML Kit. Supports two modes via mode in the config: barcode (CameraX + ML Kit barcode scanning — fast QR/barcode decode on background threads) and document (ML Kit Document Scanner — scan physical pages to digital JPEG/PDF with auto edge detection, cropping, and filters). Unlike openBarcodeScanner(), no camera frames are streamed into the WebView.
Parameters
| Name | Type | Description | Required |
| overlayConfigJson | Object | String | Scanner mode and options (see below). Pass {} for barcode/QR defaults | No |
| callback | Function | String | Callback function or name (default: onNativeScanResult) | No |
overlayConfigJson — common
| Field | Type | Description | Default |
mode | String | "barcode" for QR/barcodes, "document" for scan-to-digital pages | "barcode" |
overlayConfigJson — barcode mode
| Field | Type | Description | Default |
prompt | String | Hint text shown at the top of the scanner overlay | "Point at a QR code" |
hint | String | Alias for prompt | — |
showTorch | Boolean | Show the flashlight toggle button | true |
vibrate | Boolean | Short vibration on successful scan | true |
formats | String | Array | Barcode formats: qr, ean13, code128, all, etc. | ["qr"] |
overlayConfigJson — document mode
| Field | Type | Description | Default |
pageLimit | Number | Maximum pages per scan session (0 = unlimited) | 0 |
galleryImportAllowed | Boolean | Allow importing existing photos from gallery | true |
scannerMode | String | "base", "base_with_filter", or "full" (ML cleanup + filters) | "full" |
resultFormats | Array | Output types: ["jpeg"], ["pdf"], or ["jpeg","pdf"] | ["jpeg"] |
includePdf | Boolean | Shortcut to also request PDF when resultFormats is omitted | false |
searchablePdf | Boolean | Build a searchable PDF with OCR text layer (alias: ocr). Uses ML Kit Text Recognition + custom PDF builder. Text can be selected/copied in PDF viewers | false |
ocrLanguage | String | OCR script when searchablePdf is true: latin, chinese, japanese, korean, devanagari | latin |
Input
// Barcode / QR
Atlayo.system.showNativeScanner({
mode: 'barcode',
prompt: 'Scan payment QR',
formats: ['qr']
})
// Searchable document PDF (selectable text)
Atlayo.system.showNativeScanner({
mode: 'document',
searchablePdf: true,
ocrLanguage: 'latin',
scannerMode: 'full'
})Output / Response
// Barcode mode
{
"action": "showNativeScanner",
"mode": "barcode",
"success": true,
"text": "https://pay.example.com/abc123",
"format": "QR_CODE"
}
// Document mode
{
"action": "showNativeScanner",
"mode": "document",
"success": true,
"pageCount": 2,
"pages": [
{ "index": 0, "mimeType": "image/jpeg", "data": "<base64>" }
],
"pdf": {
"mimeType": "application/pdf",
"pageCount": 2,
"searchable": true,
"data": "<base64>"
}
}Example
// QR / barcode
Atlayo.system.showNativeScanner({ mode: 'barcode', formats: ['qr'] }, function(result) {
if (result.success) handleQrPayload(result.text);
});
// Searchable PDF — text can be selected/copied in PDF viewers
Atlayo.system.showNativeScanner({
mode: 'document',
searchablePdf: true,
ocrLanguage: 'latin'
}, function(result) {
if (result.success && result.pdf) {
Atlayo.system.downloadFile('scan.pdf', 'application/pdf', result.pdf.data);
}
});
Document mode uses Google Play services' ML Kit Document Scanner UI. Set searchablePdf: true to run ML Kit Text Recognition on each page and embed an OCR text layer (white invisible glyphs over the scan) so PDF viewers can select and search text. Requires Google Play services and ~1.7GB device RAM.
Atlayo.system.downloadFile(name, mimeType, data, callback)
Saves a file to the device's public Downloads folder. Accepts base64-encoded file content (optionally with a data:…;base64, prefix). On Android 10+ uses MediaStore scoped storage; no storage permission is required on modern devices.
Parameters
| Name | Type | Description | Required |
| name | String | Filename including extension (e.g. "receipt.pdf") | Yes |
| mimeType | String | MIME type (e.g. application/pdf, image/jpeg) | No |
| data | String | Base64 file bytes | Yes |
| callback | Function | String | Callback function or name (default: onDownloadResult) | No |
Input
Atlayo.system.downloadFile(
'scan-2026-04-12.pdf',
'application/pdf',
pdfBase64
)
Output / Response
{
"action": "downloadFile",
"success": true,
"name": "scan-2026-04-12.pdf",
"mimeType": "application/pdf",
"size": 48231,
"path": "Download/scan-2026-04-12.pdf",
"uri": "content://..."
}Example
// Save scanned document PDF to Downloads
Atlayo.system.showNativeScanner({
mode: 'document',
resultFormats: ['pdf']
}, function(scan) {
if (scan.success && scan.pdf) {
Atlayo.system.downloadFile(
'document.pdf',
'application/pdf',
scan.pdf.data,
function(dl) {
if (dl.success) Atlayo.UI.toast('Saved to Downloads');
}
);
}
});
Security: Private keys are stored in Android Keystore / Secure Enclave and cannot be exported. Signing requires biometric authentication on supported devices.
Atlayo.crypto.generateSecureKeyPair(alias, algorithm, callback)
Generate an asymmetric key pair in hardware-backed secure storage. The private key never leaves the device's secure hardware.
Parameters
| Name | Type | Description | Required |
| alias | String | Logical key name within your mini-app (e.g. "wallet_signing_key"). Scoped per mini-app automatically | Yes |
| algorithm | String | "EC" (default, P-256) or "RSA" (2048-bit) | No |
| callback | Function | String | Callback function or name (default: onKeyPairResult) | No |
Input
Atlayo.crypto.generateSecureKeyPair('wallet_signing_key', 'EC')Output / Response
{
"action": "generateSecureKeyPair",
"success": true,
"alias": "atlayo_my_app_wallet_signing_key",
"algorithm": "EC",
"publicKey": "<base64 SPKI>",
"publicKeyFormat": "SPKI",
"alreadyExists": false
}Example
Atlayo.crypto.generateSecureKeyPair('wallet_signing_key', 'EC', function(result) {
if (result.success) {
console.log('Public key:', result.publicKey);
registerPublicKeyWithBackend(result.publicKey);
} else {
Atlayo.UI.alert(result.error || 'Key generation failed');
}
});
Atlayo.crypto.signPayloadNatively(alias, payloadJson, callback)
Sign a cryptographic message or transaction payload using a hardware-protected key. Biometric authentication (fingerprint or face unlock) is required before signing.
Parameters
| Name | Type | Description | Required |
| alias | String | Key alias previously created with generateSecureKeyPair | Yes |
| payloadJson | String | Object | Payload to sign. Raw string, or object with payload, optional title / subtitle for biometric prompt | Yes |
| callback | Function | String | Callback function or name (default: onSignResult) | No |
Input
Atlayo.crypto.signPayloadNatively('wallet_signing_key', {
payload: JSON.stringify({ to: '0xABC...', amount: '1.5', nonce: 42 }),
title: 'Sign transaction',
subtitle: 'Authorize transfer of 1.5 tokens'
})Output / Response
{
"action": "signPayloadNatively",
"success": true,
"signature": "<base64>",
"algorithm": "SHA256withECDSA"
}Example
const txPayload = JSON.stringify({
to: '0xABC...',
amount: '1.5',
nonce: 42
});
Atlayo.crypto.signPayloadNatively('wallet_signing_key', {
payload: txPayload,
title: 'Sign transaction',
subtitle: 'Authorize transfer of 1.5 tokens'
}, function(result) {
if (result.success) submitSignedTransaction(txPayload, result.signature);
else Atlayo.UI.alert(result.error || 'Signing cancelled');
});
Camera vs Barcode: Use
openCamera() for photos/videos (see Camera API). Use scanBarcode() only for QR/barcode scanning.
AtlayoInterface.getLocation(requestJson)
Get current GPS coordinates. Requires gps permission.
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | Optional callback (default: onLocationResult) | Yes |
Input
{ "callback": "onLocationData" }Output / Response
{
"latitude": 50.0755, "longitude": 14.4378,
"accuracy": 12.5, "altitude": 200,
"timestamp": 1718640000000
}Example
AtlayoInterface.getLocation(JSON.stringify({ callback: "onLocationData" }));
window.onLocationData = function(result) {
if (result.error) console.error(result.error);
else console.log("Lat:", result.latitude, "Lng:", result.longitude);
};
AtlayoInterface.startMotionSensor(requestJson)
Start accelerometer and gyroscope streaming (~60 ms interval).
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | Optional callback (default: onMotionSensorData) | Yes |
Input
{ "callback": "onMotionData" }Output / Response
{
"action": "motionSensorData", "success": true,
"data": {
"accelerometer": { "x": 0.1, "y": 9.8, "z": 0.2 },
"gyroscope": { "x": 0.01, "y": 0.0, "z": 0.0 }
}
}Example
AtlayoInterface.startMotionSensor(JSON.stringify({ callback: "onMotionData" }));
window.onMotionData = function(result) {
if (result.success) console.log("Tilt X:", result.data.accelerometer.x);
};
AtlayoInterface.stopMotionSensor(requestJson)
Stop motion sensor streaming.
Example
AtlayoInterface.stopMotionSensor(JSON.stringify({}));
AtlayoInterface.scanBarcode(requestJson)
Open camera to scan a barcode or QR code.
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | Optional callback (default: onScanResult) | Yes |
Supported formats
AZTEC
CODABAR
CODE_39
CODE_93
CODE_128
DATA_MATRIX
EAN_8
EAN_13
ITF
MAXICODE
PDF_417
QR_CODE
RSS_14
UPC_A
UPC_E
UPC_EAN_EXTENSION
The detected format is returned in the format response field.
Input
{ "callback": "onBarcodeScanned" }Output / Response
{
"action": "scanBarcode", "success": true,
"text": "https://example.com", "format": "QR_CODE"
}Example
AtlayoInterface.scanBarcode(JSON.stringify({ callback: "onBarcodeScanned" }));
window.onBarcodeScanned = function(result) {
if (result.success) document.getElementById('scanResult').textContent = result.text;
};
AtlayoInterface.authenticateBiometric(requestJson)
Initiate fingerprint or face recognition.
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | Optional callback (default: onFingerprintResult) | Yes |
Input
{ "callback": "onBiometricAuth" }Output / Response
{ "action": "authenticateBiometric", "success": true }Example
AtlayoInterface.authenticateBiometric(JSON.stringify({ callback: "onBiometricAuth" }));
window.onBiometricAuth = function(result) {
if (result.success) unlockSecureContent();
else Atlayo.UI.alert('Auth failed: ' + result.error);
};
AtlayoInterface.selectContact(requestJson)
Open native contact picker (cloud-synced Atlayo contacts).
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | Optional callback (default: onContactResult) | Yes |
Output / Response
{
"action": "selectContact", "success": true,
"contact": {
"displayName": "Jane Doe",
"phoneNumbers": [{ "value": "+420123456789", "type": "mobile" }]
}
}Example
AtlayoInterface.selectContact(JSON.stringify({ callback: "onContactSelected" }));
window.onContactSelected = function(result) {
if (result.success && result.contact) {
console.log(result.contact.displayName, result.contact.phoneNumbers[0].value);
}
};Contacts are loaded from the cloud via the main app socket. Device-only contacts not synced to cloud will not appear.
AtlayoInterface.getHardwareStatus(hardwareType)
Check if a specific hardware feature is supported and enabled on the device.
Parameters
| Name | Type | Description | Required |
| hardwareType | String | One of: gps, bluetooth, nfc | Yes |
Output / Response
{
"hardware": "bluetooth",
"supported": true,
"enabled": false
}Example
AtlayoInterface.getHardwareStatus("bluetooth");
window.onHardwareStatus = function(status) {
if (status.hardware === "bluetooth" && status.supported && !status.enabled) {
// Prompt user to enable Bluetooth
}
};
AtlayoInterface.enableHardware(hardwareType)
Open the Android system settings page to let the user enable the specified hardware feature.
Parameters
| Name | Type | Description | Required |
| hardwareType | String | One of: gps, bluetooth, nfc | Yes |
Example
AtlayoInterface.enableHardware("bluetooth");
Hardware limits: Android cannot emulate Mifare Classic
or clone hardware UIDs. HCE is for custom systems where you control both reader and mini-app.
NFC Workflow
startNfcDiscovery → wait for tag
- Connect (
connectNfcA / connectMifareClassic / connectIsoDep)
- Read/write/transceive
- Close connection →
stopNfcDiscovery
AtlayoInterface.startNfcDiscovery(requestJson)
Start listening for NFC tags.
Input
{ "callback": "onNfcDiscovered" }Output / Response
{ "id": "04A1B2C3", "techs": ["android.nfc.tech.NfcA"] }
AtlayoInterface.connectNfcA(requestJson)
Connect to discovered NFC-A tag.
Input
{ "callback": "onNfcConnected" }Output / Response
{ "success": true, "message": "Connected" }
AtlayoInterface.transceiveNfcA(requestJson)
Send APDU command to NFC-A tag.
Input
{ "data": "FFCA000000", "callback": "onNfcTransceiveResult" }Output / Response
{ "response": "0400" }
AtlayoInterface.closeNfcA()
Close NFC-A connection.
AtlayoInterface.connectMifareClassic(requestJson)
Connect to MifareClassic tag.
Input
{ "callback": "onMifareConnected" }Output / Response
{ "success": true }
AtlayoInterface.authenticateSectorWithKeyA(requestJson)
Authenticate MifareClassic sector with Key A.
Input
{ "sector": 0, "key": "FFFFFFFFFFFF" }Output / Response
{ "success": true }
AtlayoInterface.readBlockMifareClassic(requestJson)
Read 16-byte block (authenticate sector first).
Output / Response
{ "data": "00112233445566778899AABBCCDDEEFF" }
AtlayoInterface.writeBlockMifareClassic(requestJson)
Write 16-byte block (32 hex chars).
Input
{ "block": 4, "data": "00112233445566778899AABBCCDDEEFF" }Output / Response
{ "success": true }
AtlayoInterface.closeMifareClassic()
Close MifareClassic connection.
AtlayoInterface.connectIsoDep(requestJson)
Connect to IsoDep tag (smart cards, EMV, passports).
Output / Response
{ "success": true }
AtlayoInterface.transceiveIsoDep(requestJson)
Send APDU to IsoDep tag.
Input
{ "data": "00A4040007A0000000031010" }Output / Response
{ "response": "9000" }
AtlayoInterface.closeIsoDep()
Close IsoDep connection.
AtlayoInterface.readIsoDepAids(requestJson)
Reads supported Application IDs (AIDs) from a connected IsoDep card by querying the PPSE directory.
Parameters
| Name | Type | Description | Required |
| requestJson | String (JSON) | callback | No |
Input
{ "callback": "onIsoDepAidsResult" }Output / Response
{ "success": true, "aids": ["A0000000031010", "A0000000041010"] }Not all IsoDep cards support the PPSE directory. If missing, it returns an error.
Example
AtlayoInterface.readIsoDepAids(JSON.stringify({ callback: "onMyAidsResult" }));
window.onMyAidsResult = function(result) {
console.log(result.aids);
};
AtlayoInterface.stopNfcDiscovery()
Stop NFC tag discovery.
AtlayoInterface.emulateNfcCard(requestJson)
Host Card Emulation — phone acts as NFC card. Reader must SELECT AID F0010203040506.
Input
{ "data": "48656C6C6F", "callback": "onNfcEmulationResult" }Output / Response
{ "action": "cardRead" } // when reader taps phone
AtlayoInterface.stopNfcEmulation()
Stop NFC card emulation.
Permissions: Requires system Bluetooth permissions and user authorization for the specific Mini-App. These are handled automatically by the API.
AtlayoInterface.openBluetoothAdapter(requestJson)
Initializes the Bluetooth adapter. If permissions are missing, prompts the user.
Input
{ "callback": "onBluetoothAdapterOpened" }Output / Response
{ "success": true, "message": "Bluetooth adapter initialized" }
AtlayoInterface.startBluetoothDevicesDiscovery(requestJson)
Starts scanning for nearby BLE devices. Calls the callback each time a device is found. Optionally, pass an array of `services` (UUIDs) to filter the scan.
Input
{ "services": ["180D", "180F"], "callback": "onBluetoothDeviceFound" }Output / Response
{ "device": { "name": "SmartBulb", "deviceId": "00:11:22:33:44:55", "rssi": -65 } }
AtlayoInterface.stopBluetoothDevicesDiscovery(requestJson)
Stops the ongoing BLE device scan.
Input
{ "callback": "onBluetoothDiscoveryStopped" }Output / Response
{ "success": true, "message": "Discovery stopped" }
AtlayoInterface.createBLEConnection(requestJson)
Connects to a specific BLE device by its deviceId (MAC address).
Input
{ "deviceId": "00:11:22:33:44:55", "callback": "onBLEConnectionStateChange" }Output / Response
{ "deviceId": "00:11:22:33:44:55", "connected": true, "status": 0 }
AtlayoInterface.writeBLECharacteristicValue(requestJson)
Writes data to a specific characteristic on a connected BLE device. The value must be encoded as a Base64 string.
Input
{
"deviceId": "00:11:22:33:44:55",
"serviceId": "0000180d-0000-1000-8000-00805f9b34fb",
"characteristicId": "00002a37-0000-1000-8000-00805f9b34fb",
"value": "AQI=", // Base64 encoded payload
"callback": "onWriteComplete"
}Output / Response
{ "success": true, "message": "Write initiated" }
window.onBLECharacteristicValueChange(result)
Global callback triggered when a characteristic's value changes (notifications/indications). Ensure you assign this function in your mini-app's global scope.
Output / Response
{
"deviceId": "00:11:22:33:44:55",
"serviceId": "0000180d-0000-1000-8000-00805f9b34fb",
"characteristicId": "00002a37-0000-1000-8000-00805f9b34fb",
"value": "AQI=" // Base64 encoded payload
}
User controls: Tap = photo, hold ~0.5s = video.
Preview shows Cancel / Send. Only Send delivers media to your callback.
AtlayoInterface.openCamera(callback)
AtlayoInterface.openCamera(options, callback)
Open full-screen camera overlay. Callback runs once when user sends or cancels. Use fullScreen: false to keep the themed status bar and lay the camera out below it.
Parameters
| Name | Type | Description | Required |
| callback | Function | Called with result object (legacy: pass as first argument only) | Yes |
| options | Object | Optional settings when using openCamera(options, callback) | No |
| options.fullScreen | Boolean | When true (default), camera extends edge-to-edge under a transparent status bar. When false, status bar stays as before and content starts below it. | No |
Input
// Default: edge-to-edge under transparent status bar
AtlayoInterface.openCamera(function(result) { ... });
// Keep status bar / inset layout
AtlayoInterface.openCamera({ fullScreen: false }, function(result) { ... });Output / Response
{
"success": true,
"type": "image",
"mimeType": "image/jpeg",
"file": ""
}
// Cancelled:
{ "success": false, "error": "Cancelled" }Example
if (typeof AtlayoInterface.openCamera === 'function') {
AtlayoInterface.openCamera({ fullScreen: true }, function(result) {
if (!result.success) return;
const url = URL.createObjectURL(result.file);
document.getElementById('preview').src = url;
});
} else {
Atlayo.UI.alert('Camera not available on this platform');
}
Display & Upload
// Preview captured media
const blob = result.file instanceof Blob ? result.file
: new Blob([result.file], { type: result.mimeType });
const url = URL.createObjectURL(blob);
document.getElementById('myPhotoPreview').src = url;
// Remember: URL.revokeObjectURL(url) when done
// Upload to server
const formData = new FormData();
formData.append('media', result.file, result.file.name || 'capture');
fetch('https://your-server.example/upload', { method: 'POST', body: formData });
File Picker Fallback (Desktop & Gallery)
<input type="file" id="mediaPicker" accept="image/*,video/*" style="display:none" />
<button onclick="document.getElementById('mediaPicker').click()">Select Media</button>
document.getElementById('mediaPicker').addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
const url = URL.createObjectURL(file);
// show in <img> or <video> same as camera result
});
Reserved IDs: Do not use cameraVideo,
cameraPreviewVideo, or cameraPreviewImg — they conflict with the injected camera UI.
Dialog-style methods return a wrapper with .hide(callback) for manual dismissal. Atlayo.UI is injected into the WebView after the page loads. Listen for the atlayo-ui-ready event or assign window.__onAtlayoUIReady before calling overlay components.
All Atlayo.UI Methods
| Method | Type | Description |
Atlayo.UI.dialog(options) | Overlay | Base dialog with custom title, content, and buttons |
Atlayo.UI.alert(message, options) | Overlay | Alert dialog with OK button |
Atlayo.UI.confirm(message, options) | Overlay | Confirmation dialog with multiple buttons |
Atlayo.UI.toast(message, options) | Overlay | Temporary success/info toast |
Atlayo.UI.loading(message, options) | Overlay | Loading spinner; call .hide() to dismiss |
Atlayo.UI.actionSheet(menus, actions, options) | Overlay | Bottom sheet with menu and cancel action rows |
Atlayo.UI.topTips(content, options) | Overlay | Top error/warning tip banner |
Atlayo.UI.picker(items, options) | Overlay | Single-, multi-, or cascading column picker |
Atlayo.UI.datePicker(options) | Overlay | Year / month / day picker |
Atlayo.UI.form.validate(selector, callback, options) | DOM | Validate a form on submit |
Atlayo.UI.form.checkIfBlur(selector, options) | DOM | Validate inputs on blur |
Atlayo.UI.form.showErrorTips(error) | DOM | Show field validation error as topTips |
Atlayo.UI.form.hideErrorTips(ele) | DOM | Hide validation error for an input |
Atlayo.UI.dialog(options)
Base dialog component. alert and confirm are built on top of this.
Parameters
| Name | Type | Description | Required |
| options.title | String | Dialog title | No |
| options.content | String | Dialog body text | No |
| options.className | String | Custom CSS class | No |
| options.buttons | Array | Buttons: label, type (primary | default | warn), onClick | No |
Returns
Dialog wrapper with .hide(callback) to close manually.
Example
const dlg = Atlayo.UI.dialog({
title: 'Confirm action',
content: 'Proceed with this operation?',
buttons: [
{ label: 'Cancel', type: 'default' },
{ label: 'OK', type: 'primary', onClick: function() { console.log('ok'); } }
]
});
Atlayo.UI.alert(message, options)
Show a native-style alert dialog.
Parameters
| Name | Type | Description | Required |
| message | String | Message text | Yes |
| options.title | String | Dialog title | No |
| options.buttons | Array | Buttons with label, type, optional onClick | No |
Input
Atlayo.UI.alert("Saved!", { title: "Success", buttons: [{ label: "OK", type: "primary" }] })Example
alert("Hello!"); // uses Atlayo.UI.alert automatically
Atlayo.UI.alert("Do you want to continue?", {
title: "Confirm",
buttons: [
{ label: "Cancel", type: "default" },
{ label: "OK", type: "primary" }
]
});
Atlayo.UI.confirm(message, options)
Show a confirmation dialog with action buttons.
Parameters
| Name | Type | Description | Required |
| message | String | Message text | Yes |
| options.buttons | Array | Buttons with label, type, onClick | Yes |
Input
Atlayo.UI.confirm("Delete this item?", { title: "Delete", buttons: [...] })Example
Atlayo.UI.confirm("Are you sure?", {
title: "Delete Item",
buttons: [
{ label: "Cancel", type: "default" },
{ label: "Delete", type: "warn", onClick: function() { deleteItem(); } }
]
});
Atlayo.UI.toast(message, options)
Show a temporary toast at the top of the screen.
Parameters
| Name | Type | Description | Required |
| message | String | Toast text | Yes |
| options.duration | Number | Duration in ms (default: 3000) | No |
| options.className | String | Custom CSS class | No |
| options.callback | Function | Called when toast closes | No |
Input
Atlayo.UI.toast("Settings saved", { duration: 2000 })Example
Atlayo.UI.toast("Connection successful", { duration: 3000 });
Atlayo.UI.toast("Saved!", { duration: 2000, callback: function() { console.log('closed'); } });
Atlayo.UI.loading(message, options)
Show loading indicator. Returns a wrapper with .hide(callback).
Parameters
| Name | Type | Description | Required |
| message | String | Loading message | No |
| options.className | String | Custom CSS class | No |
Input
const loading = Atlayo.UI.loading("Loading...");Output / Response
loading.hide(callback) — call to dismiss
Example
const hideLoading = Atlayo.UI.loading("Loading data...");
fetch('/api/data').then(r => r.json()).then(data => {
hideLoading.hide();
renderData(data);
});
Atlayo.UI.actionSheet(menus, actions, options)
Show a bottom action sheet. menus are the primary options; actions is typically a cancel row at the bottom.
Parameters
| Name | Type | Description | Required |
| menus | Array | Primary actions: label, optional onClick | Yes |
| actions | Array | Secondary actions (e.g. Cancel): label, onClick | Yes |
| options.title | String | Sheet title | No |
| options.className | String | Custom CSS class | No |
| options.onClose | Function | Called when sheet closes | No |
Example
Atlayo.UI.actionSheet([
{ label: "Take Photo", onClick: function() {
AtlayoInterface.openCamera(function(r) {
if (r.success) Atlayo.UI.toast('Captured!');
});
}},
{ label: "Choose from Gallery", onClick: openGallery }
], [
{ label: "Cancel", onClick: function() {} }
], { title: "Select Image Source" });
Atlayo.UI.topTips(content, options)
Show a temporary tip banner at the top of the screen (typically for validation errors).
Parameters
| Name | Type | Description | Required |
| content | String | Tip message text | Yes |
| options | Number | Object | Duration in ms, or config object | No |
| options.duration | Number | Auto-hide delay in ms (default: 3000) | No |
| options.className | String | Custom CSS class | No |
| options.callback | Function | Called when tip closes | No |
Example
Atlayo.UI.topTips('Please fill in all required fields', 3000);
const tip = Atlayo.UI.topTips('Invalid email', { duration: 3000, callback: function() {} });
tip.hide(); // dismiss manually
Atlayo.UI.picker(items, options) — or picker(col1, col2, options) / picker(col1, col2, col3, options)
Multi-column picker for single, multi-column, or cascading selections. Each item: { label, value, disabled?, children? }.
Parameters
| Name | Type | Description | Required |
| items | Array | Picker data (1–3 columns; use multiple args for multi-column) | Yes |
| options.defaultValue | Array | Pre-selected values | No |
| options.title | String | Picker title | No |
| options.depth | Number | Column count 1–3 (inferred from data if omitted) | No |
| options.onChange | Function | Called when selection changes | No |
| options.onConfirm | Function | Called with selected value array on confirm | No |
| options.id | String | Cache key for remembered selection | No |
Example
// Single column
Atlayo.UI.picker([
{ label: 'Option A', value: 0 },
{ label: 'Option B', value: 1 }
], { defaultValue: [1], onConfirm: function(result) { console.log(result); } });
// Cascading (e.g. category → subcategory)
Atlayo.UI.picker([
{ label: 'Food', value: 0, children: [{ label: 'Pizza', value: 1 }] },
{ label: 'Drink', value: 1, children: [{ label: 'Water', value: 2 }] }
], { defaultValue: [0, 1], onConfirm: function(r) { console.log(r); } });
Atlayo.UI.datePicker(options)
Date picker for year, month, and day selection.
Parameters
| Name | Type | Description | Required |
| options.start | Number | String | Date | Start year or date (default: 2000) | No |
| options.end | Number | String | Date | End year or date (default: 2030) | No |
| options.defaultValue | Array | Default [year, month, day], e.g. [1991, 6, 9] | No |
| options.cron | String | Restrict selectable days, e.g. "* * 0,6" for weekends only | No |
| options.onChange | Function | Called when date changes | No |
| options.onConfirm | Function | Called with [year, month, day] on confirm | No |
Example
Atlayo.UI.datePicker({
start: 1990,
end: 2030,
defaultValue: [1991, 6, 9],
onConfirm: function(result) { console.log(result); } // [1991, 6, 9]
});
Atlayo.UI.form.validate(selector, callback, options)
Form validation helpers. Inputs use required, pattern, emptyTips, and notMatchTips attributes.
Methods
| Method | Description |
form.validate(selector, callback, options) | Validate all fields in a form; callback receives error object or null |
form.checkIfBlur(selector, options) | Validate individual fields on blur |
form.showErrorTips(error) | Show validation error via topTips (error.ele, error.msg) |
form.hideErrorTips(ele) | Hide error tips for a specific input element |
Example
<form id="myForm">
<input type="tel" required pattern="[0-9]{11}"
emptyTips="Enter phone" notMatchTips="Invalid phone">
</form>
Atlayo.UI.form.validate('#myForm', function(error) {
if (!error) {
const loading = Atlayo.UI.loading('Submitting...');
submitForm().finally(function() { loading.hide(); });
}
}, { regexp: { IDNUM: /^\d{17}[\dXx]$/ } });
Multi-API Mini-App Starter
<!DOCTYPE html>
<html><head><title>My Mini-App</title></head>
<body>
<h1>My Mini-App</h1>
<button onclick="requestUserData()">Get User Data</button>
<button onclick="scanQR()">Scan QR</button>
<button onclick="saveData()">Save Data</button>
<div id="userName"></div>
<div id="scanResult"></div>
<script>
window.addEventListener('load', function() {
if (typeof AtlayoInterface === 'undefined') return;
const info = JSON.parse(AtlayoInterface.getSystemInfo());
if (info.darkMode) document.body.classList.add('dark-mode');
});
function requestUserData() {
AtlayoInterface.requestPermissions(JSON.stringify(["given_name", "family_name"]));
}
window.onPermissionsGranted = function(data) {
document.getElementById('userName').textContent = data.given_name + ' ' + data.family_name;
Atlayo.UI.alert("Welcome " + data.given_name + "!");
};
function scanQR() { AtlayoInterface.scanBarcode(JSON.stringify({})); }
window.onScanResult = function(r) {
if (r.success) document.getElementById('scanResult').textContent = r.text;
};
function saveData() {
AtlayoInterface.setStorage(JSON.stringify({
key: "my_data", data: { ts: Date.now() }, callback: "onSaved"
}));
}
function onSaved(r) { Atlayo.UI.toast(r.success ? "Saved!" : "Failed"); }
</script>
</body></html>
Payment with Loading
function makePayment() {
const hide = Atlayo.UI.loading('Processing payment...');
atlayo_pay({
amount: 10.00, api_key: 'pk_YOUR_KEY', description: 'Product',
callback: function(result) {
hide();
if (result.success) enableProductAccess();
else Atlayo.UI.alert('Failed: ' + result.error);
}
});
}