قابلیتهای دستگاه
حسگرها، فایلها و کارهای پسزمینه
حسگرهای BLE تناسب اندام را جفت کنید، فایلهای FIT/GPX/TCX دریافت کنید، کارها را وقتی بسته است اجرا کنید
1فایل، عکس، ویدیو و پیوند را از اپلیکیشنهای دیگر دریافت کنید#
در جادوگر «Receive Shares From Other Apps» را روشن کنید و آنچه اپلیکیشن شما میپذیرد را تیک بزنید - متن و پیوند، فایلهای داده (FIT، GPX، TCX، CSV، JSON، XML…)، عکس، ویدیو، صدا، سند. اپلیکیشن شما دقیقاً برای همان انواع در دو جا ظاهر میشود:
- برگه «Open with» در Android وقتی کاربر روی یک فایل میزند.
- برگه SHARE / EXPORT که اپلیکیشنهای دیگر نشان میدهند - از جمله دستگاههای ورزشی که فایلهای تمرین (.fit، .gpx، .tcx) خروجی میگیرند. بیشتر اپلیکیشنهای تناسب اندام از طریق Share خروجی میگیرند، به همین دلیل اپلیکیشنهایی که فقط 'Open with' را ثبت میکنند آنجا هرگز ظاهر نمیشوند.
فایل را با AppMint.getOpenedFile() بخواهید - هر چقدر هم صفحه شما دیر شروع شود منتظر میماند. f.kind یکی از image، video، audio، document یا data است. فرمتهای متنی (gpx، tcx، csv، json، xml…) به صورت f.text آماده میرسند؛ باینریهای کوچک (.fit) به صورت f.base64؛ هر فایل داده و سند به صورت یک File واقعی در f.file. عکسها، ویدیوها و صداها به صورت f.url میرسند، نشانی قابل پخش برای <video src> / <img src>، با f.getFile() وقتی بایتها را لازم دارید. محدودیت اندازه ندارد. پیوند یا عنوان اشتراکگذاریشده با WebToApk.getSharedText() خوانده میشود.
// Ask on startup — the file waits, however late your page mounts
const f = await AppMint.getOpenedFile(); // null if opened normally
if (f) {
if (f.name.endsWith('.gpx') || f.name.endsWith('.tcx')) {
const xml = new DOMParser().parseFromString(f.text, 'text/xml');
const points = xml.querySelectorAll('trkpt, Trackpoint');
console.log('workout with ' + points.length + ' points');
} else if (f.name.endsWith('.fit')) {
// .fit is binary — a real File; parse its bytes
parseFit(new Uint8Array(await f.file.arrayBuffer())); // e.g. fit-file-parser
} else if (f.kind === 'video') {
document.querySelector('video').src = f.url; // streams from disk, seekable
}
}
// A shared link or caption
const shared = JSON.parse(WebToApk.getSharedText() || 'null');
if (shared) console.log('shared:', shared.url || shared.text);2حسگرهای تناسب اندام بلوتوث را جفت کنید (ضربان قلب، سرعت، کادانس…)#
مجوز بلوتوث را در جادوگر روشن کنید و اپلیکیشن شما میتواند حسگرهای استاندارد BLE را جفت کند - هر کمربند سینه و پاد دوچرخه سازگار از همان پروفایلهای رسمی بلوتوث استفاده میکند، پس برای هر برند کد جداگانه لازم نیست:
- کمربندهای ضربان قلب ← bpm
- پادهای سرعت/کادانس ← km/h + دور پدال در دقیقه
- توانسنجها ← وات
- پاد دویدن ← سرعت دویدن + گام در دقیقه
- سطح باتری هر حسگر
جریان: اسکن (15 ثانیه) ← کاربر یک دستگاه انتخاب میکند ← اتصال. سپس دادهها به صورت رویداد جریان مییابند. سرعت به اندازه چرخ شما نیاز دارد؛ یک بار تنظیمش کنید (پیشفرض 2096mm = چرخ جاده 700x23c).
// 1. Scan — each found sensor fires a 'device' event:
window.addEventListener('appmint:ble', function (e) {
const m = e.detail;
if (m.kind === 'device') {
// {address, name, sensors:['heart_rate','speed_cadence',...], rssi}
addToPickerUI(m);
}
if (m.kind === 'data') {
if (m.type === 'heart_rate') showBpm(m.data.bpm);
if (m.type === 'speed_cadence') {
if (m.data.speedKmh) showSpeed(m.data.speedKmh.toFixed(1));
if (m.data.cadenceRpm) showCadence(Math.round(m.data.cadenceRpm));
}
if (m.type === 'power') showWatts(m.data.watts);
if (m.type === 'battery') showBattery(m.data.percent);
}
if (m.kind === 'error') console.warn('BLE:', m.error);
});
WebToApk.bleSetWheelCircumference(2105); // your wheel, in mm
WebToApk.bleStartScan();
// 2. When the user taps a device from your picker:
WebToApk.bleConnect(device.address);
// 3. Done training:
WebToApk.bleDisconnect();3کارهای پسزمینه و ذخیره خودکار پایدار (WorkManager)#
جاوااسکریپت نمیتواند وقتی اپلیکیشن شما بسته است اجرا شود - این Android است، نه AppMint. چیزی که میتواند اجرا شود یک کار تحویل بومی است که صفحه شما به سیستمعامل میسپارد. دو ابزار:
- workEnqueueOnline - تحویل یکباره پایدار. ذخیره خودکار عالی: داده را بسپارید و هر وقت شبکه باشد به سرور شما POST میشود، با تلاش مجدد و عقبنشینی، و از بسته شدن اپلیکیشن و راهاندازی دوباره جان سالم به در میبرد. استفاده دوباره از همان شناسه کار، ذخیره در انتظار را با جدیدترین وضعیت جایگزین میکند.
- workSchedulePeriodic - یک فراخوانی HTTP بومی تکرارشونده (راهانداز همگامسازی، heartbeat). حداقل فاصله Android 15 دقیقه است؛ مقادیر کوتاهتر به آن گرد میشوند.
هر دو محموله شما را به نشانی شما میرسانند - سمت سرور یک نقطه پایانی معمولی است که از قبل دارید (edge function در Supabase، API خودتان…).
// Durable auto-save: call this on every important change.
function autoSave(state) {
WebToApk.workEnqueueOnline(
'autosave', // same id → newest state wins
'https://api.example.com/save',
'POST',
JSON.stringify({ 'Authorization': 'Bearer ' + token }),
JSON.stringify(state)
);
}
// Recurring sync every 30 minutes, even if the app is closed:
WebToApk.workSchedulePeriodic(
'sync', 'https://api.example.com/sync', 'POST', '{}', '', 30
);
// Manage jobs:
WebToApk.workCancel('sync');
WebToApk.workList('req1');
window.addEventListener('appmint:work', function (e) {
// {id, status:'enqueued'|'scheduled'|'cancelled'|'failed', reason?, intervalMinutes?}
// or, for workList: {requestId, jobs:[{id, periodic, url, createdAt, pendingDelivery}]}
console.log('work:', e.detail);
});4چکلیست و اشتباهات رایج#
- فایلها: کلید باید هنگام ساخت روشن باشد - اپلیکیشن شما را در manifest Android ثبت میکند که پس از نصب قابل تغییر نیست. پس از فعالسازی دوباره بسازید.
- BLE: کلید مجوز بلوتوث باید هنگام ساخت روشن باشد. اولین اسکن از کاربر مجوز زمان اجرا را میخواهد (Android 12+: 'Nearby devices'؛ قدیمیتر: Location - این یک قانون Android برای اسکن BLE است، اپلیکیشن شما موقعیت مکانی را نمیخواند).
- BLE: در اپلیکیشن خودتان جفت کنید، نه در تنظیمات بلوتوث Android - حسگرهای BLE تناسب اندام دستگاههای جفتشده کلاسیک نیستند.
- کارهای پسزمینه: یک کار دورهای را برای «اجرای کد صفحه من» زمانبندی نکنید - آن HTTP را به سرور شما تحویل میدهد. اگر پردازش روی دستگاه هنگام بسته بودن لازم دارید، نقطه پایانی تحویل برای همین است.
- ذخیره خودکار: همیشه همان شناسه کار. شناسههای متفاوت چند ذخیره قدیمی را در صف میگذارند.