Mobile Actions

Tích hợp camera, GPS, QR scanner, và các tính năng native của điện thoại vào dashboard widget.

Mobile Actions

Mobile Actions cho phép widget trong dashboard gọi các tính năng native của điện thoại: chụp ảnh, quét QR code, lấy tọa độ GPS, gọi điện...

Cách cấu hình

  1. Mở dashboard → Edit
  2. Click vào widget cần thêm action → Edit widget
  3. Tab Actions → click + để thêm
  4. Action type: Chọn "Mobile action"
  5. Chọn loại mobile action (xem bên dưới)
  6. Cấu hình JavaScript function tương ứng

Các loại Mobile Action

1. Chụp ảnh từ thư viện (Take picture from gallery)

Mở thư viện ảnh để người dùng chọn ảnh.

processImage(imageUrl) — Nhận base64 URL của ảnh đã chọn:

// Ví dụ: upload ảnh lên server và lưu URL vào attributes var entityId = widgetContext.currentUser.userId; widgetContext.http.post( '/api/plugins/telemetry/USER/' + entityId + '/attributes/SERVER_SCOPE', JSON.stringify({ devicePhoto: imageUrl }) ).subscribe(() => { widgetContext.showSuccessToast('Ảnh đã được lưu!'); });

2. Chụp ảnh (Take Photo)

Mở camera để chụp ảnh trực tiếp.

processImage(imageUrl) — Tương tự Take picture from gallery.

// Lưu ảnh thiết bị vào telemetry var ts = Date.now(); var deviceId = widgetContext.defaultSubscription.configuredDatasources[0].entityId; widgetContext.http.post( '/api/plugins/telemetry/DEVICE/' + deviceId + '/timeseries/SERVER_SCOPE', JSON.stringify({ ts: ts, values: { photo: imageUrl } }) ).subscribe(() => { widgetContext.showSuccessToast('Ảnh đã được ghi lại!'); });

3. Chỉ đường (Open map directions)

Mở app bản đồ chỉ đường đến vị trí.

getLocation() — Trả về object {latitude, longitude}:

// Lấy tọa độ từ server attribute của thiết bị return { latitude: parseFloat(widgetContext.defaultSubscription.data[0].data[0][1]), longitude: parseFloat(widgetContext.defaultSubscription.data[1].data[0][1]) };

4. Xem vị trí trên bản đồ (Open map location)

Hiển thị vị trí trên bản đồ (không chỉ đường).

getLocation() — Giống Open map directions.


5. Quét QR Code (Scan QR code)

Mở camera quét QR code. Phổ biến cho claiming device.

processQrCode(qrCode) — Nhận nội dung QR code:

// Claim device bằng QR code (secret key) var claimRequest = { secretKey: qrCode, durationMs: 60000 }; widgetContext.http.post( '/api/customer/device/' + widgetContext.currentUser.customerId + '/claim', JSON.stringify(claimRequest) ).subscribe( (result) => widgetContext.showSuccessToast('Thiết bị đã được thêm: ' + result.name), (error) => widgetContext.showErrorToast('Lỗi: ' + error.message) );

6. Gọi điện (Make phone call)

Mở dialer với số điện thoại.

getPhoneNumber() — Trả về số điện thoại:

// Lấy số điện thoại từ attribute return widgetContext.defaultSubscription.data[0].data[0][1]; // Ví dụ return: "0901234567"

7. Lấy vị trí GPS (Get phone location)

Lấy tọa độ GPS của điện thoại người dùng.

processLocation(location) — Nhận {latitude, longitude}:

// Lưu vị trí hiện tại vào telemetry thiết bị var deviceId = widgetContext.defaultSubscription.configuredDatasources[0].entityId; widgetContext.http.post( '/api/plugins/telemetry/DEVICE/' + deviceId + '/timeseries/SERVER_SCOPE', JSON.stringify({ latitude: location.latitude, longitude: location.longitude, locationUpdatedAt: Date.now() }) ).subscribe(() => { widgetContext.showSuccessToast('Vị trí đã được cập nhật!'); });

8. Chụp màn hình (Take screenshot)

Chụp screenshot của widget/dashboard.

processImage(imageUrl) — Nhận base64 URL của screenshot.


Quyền (Permissions) cần khai báo

Android (AndroidManifest.xml)

<!-- Camera --> <uses-permission android:name="android.permission.CAMERA" /> <!-- Storage --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Location --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Phone --> <uses-permission android:name="android.permission.CALL_PHONE" />

iOS (Info.plist)

<key>NSCameraUsageDescription</key> <string>VieLang cần camera để chụp ảnh thiết bị</string> <key>NSPhotoLibraryUsageDescription</key> <string>VieLang cần truy cập thư viện ảnh</string> <key>NSLocationWhenInUseUsageDescription</key> <string>VieLang cần vị trí để theo dõi thiết bị</string>

Ví dụ thực tế: Widget báo cáo sự cố

Dashboard kỹ thuật viên với button "Báo cáo sự cố":

// getPhoneNumber() — gọi hotline kỹ thuật return "19001800"; // processImage() — lưu ảnh sự cố var deviceId = widgetContext.defaultSubscription.configuredDatasources[0].entityId; widgetContext.http.post( '/api/plugins/telemetry/DEVICE/' + deviceId + '/attributes/SERVER_SCOPE', JSON.stringify({ incidentPhoto: imageUrl, incidentTime: Date.now() }) ).subscribe(() => { widgetContext.showSuccessToast('Sự cố đã được ghi nhận'); });