פתיחת קורקינט באמצעות BLE/QR באפליקציית מובייל

כאשר משתמשים חווים עיכובים או כשלים בפתיחת קורקינט, האמון בשירות יורד מיידית. אנו בונים מערכת פתיחה באמצעות BLE/QR הפועלת במהירות ובאמינות, והצוות שלנו מספק את הפרויקט במתכונת turnkey—מסריקת הקוד ועד שליחת הפקודה למנעול—עם תמיכה מתמשכת.

פיתוח ותמיכה בכל סוגי היישומים הניידים:

יישומים ניידים למידע ובידור
אפליקציות חדשות, משחקים, מדריכים, קטלוגים מקוונים, אפליקציות מזג אוויר, אפליקציות כושר ובריאות, אפליקציות נסיעות, אפליקציות חינוכיות, רשתות חברתיות ומסנג'רים, חידונים, בלוגים ופודקאסטים, פורומים, אגרגטורים
יישומים ניידים למסחר אלקטרוני
חנויות מקוונות, אפליקציות B2B, מרקטפלייסים, בורסות מקוונות, שירותי קאשבק, בורסות, פלטפורמות דרופשיפינג, תוכניות נאמנות, משלוחי מזון ומוצרים, מערכות תשלום.
יישומים ניידים לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, ניהול פרויקטים, כלים לצוותי מכירות, ניהול פיננסי, ניהול ייצור, ניהול לוגיסטיקה ומשלוחים, ניהול משאבי אנוש, מערכות ניטור נתונים
יישומים ניידים לשירותים אלקטרוניים
פלטפורמות מודעות מסווגות, בתי ספר מקוונים, בתי קולנוע מקוונים, פלטפורמות שירות אלקטרוניות, פלטפורמות קאשבק, אירוח וידאו, פורטלים נושאיים, פלטפורמות הזמנות ותזמון מקוונות, פלטפורמות מסחר מקוונות

אלה הם רק חלק מסוגי היישומים הניידים שאנו עובדים איתם, ולכל אחד מהם עשויים להיות מאפיינים ופונקציונליות ספציפיים משלו, המותאמים לצרכים ולמטרות הספציפיות של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
פתיחת קורקינט באמצעות BLE/QR באפליקציית מובייל
בינוני
~1-2 שבועות

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

פתיחת קורקינט באמצעות BLE/QR באפליקציה ניידת

אנו מפתחים מערכות פתיחה לקורקינטים חשמליים באמצעות אפליקציה ניידת. המשתמש סורק קוד QR, האפליקציה שלנו מתקשרת עם השרת ושולחת פקודת BLE—הכל תוך שניות. עם ניסיון של 5+ שנים בעבודה על 10+ פרויקטים של שיתוף, אנו יודעים: כל תקלה בנתיב הזה פוגעת מיד באמון בשירות. כל עיכוב נתפס כבאג, ולכן אנו שמים לב לכל אלפית שנייה. אחד הלקוחות שלנו, שהשיק שירות שיתוף קורקינטים בעיר עם 500 קורקינטים, גילה ש-15% מהמשתמשים נטשו את ההשכרה בשלב הפתיחה—בגלל חיבור BLE איטי. ייעלנו את הפרוטוקול, ושיעור הנטישה ירד ל-3%.

איך פועלת פתיחת QR

ה-QR על הקורקינט מקודד את מזהה המכשיר: מחרוזת כמו https://ride.example.com/unlock?id=SC-00234 או פשוט SC-00234. אנו סורקים באמצעות ML Kit Barcode Scanning (Android/iOS) או AVFoundation AVCaptureMetadataOutput. ML Kit עדיף—הוא עובד ללא חיבור רשת ומהיר יותר בתנאי תאורה נמוכה.

לאחר קבלת המזהה, אנו שולחים בקשה לשרת: POST /api/v1/unlock עם {scooterId, userId, sessionToken}. השרת בודק את היתרה/המנוי, מזמין את הקורקינט, ומחזיר {bleUnlockToken, bleDeviceAddress, lockServiceUUID, lockCharacteristicUUID, expiresAt}. הטוקן הוא חד-פעמי, תקף ל-30–60 שניות—אם חיבור ה-BLE נכשל בזמן, המשתמש מקבל שגיאה ומתחיל בקשה חדשה.

// iOS: сканирование QR через AVFoundation
class QRScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        guard let readableObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
              let stringValue = readableObject.stringValue,
              let scooterId = parseScooterId(from: stringValue) else { return }
        captureSession.stopRunning()
        Task {
            await viewModel.initiateUnlock(scooterId: scooterId)
        }
    }
}

למה טוקן BLE פג תוקף

קורקינטים בשיתוף משתמשים במודולי BLE המבוססים על Nordic nRF52 או ESP32 עם פרופיל GATT מותאם אישית. התוכנית פשוטה: אנו כותבים את הטוקן ל-// iOS: сканирование QR через AVFoundation class QRScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { guard let readableObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject, let stringValue = readableObject.stringValue, let scooterId = parseScooterId(from: stringValue) else { return } captureSession.stopRunning() Task { await viewModel.initiateUnlock(scooterId: scooterId) } } } , הבקר מאמת את חתימת ה-HMAC (מפתח משותף המוטמע בקושחה), ואם היא תואמת, משחרר את המנעול האלקטרומגנטי ומאפשר את המנוע.

// Android: запись unlock-токена в BLE characteristic
class ScooterUnlockManager(private val context: Context) {
    private var gatt: BluetoothGatt? = null

    suspend fun unlock(address: String, token: UnlockToken): UnlockResult {
        return suspendCancellableCoroutine { cont ->
            val device = bluetoothAdapter.getRemoteDevice(address)
            gatt = device.connectGatt(context, false, object : BluetoothGattCallback() {
                override fun onConnectionStateChange(g: BluetoothGatt, status: Int, state: Int) {
                    if (state == BluetoothProfile.STATE_CONNECTED)
                        g.discoverServices()
                    else if (status != BluetoothGatt.GATT_SUCCESS) {
                        cont.resume(UnlockResult.BleConnectionFailed(status))
                    }
                }

                override fun onServicesDiscovered(g: BluetoothGatt, status: Int) {
                    val characteristic = g
                        .getService(token.serviceUUID)
                        ?.getCharacteristic(token.characteristicUUID)
                        ?: run {
                            cont.resume(UnlockResult.ServiceNotFound)
                            return
                        }
                    characteristic.value = token.payload.toByteArray()
                    characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
                    g.writeCharacteristic(characteristic)
                }

                override fun onCharacteristicWrite(g: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
                    val result = if (status == BluetoothGatt.GATT_SUCCESS)
                        UnlockResult.Success
                    else
                        UnlockResult.WriteFailed(status)
                    cont.resume(result)
                    g.disconnect()
                }
            }, BluetoothDevice.TRANSPORT_LE)
            cont.invokeOnCancellation { gatt?.disconnect() }
        }
    }
}

פרט קריטי: WriteCharacteristic ב-// Android: запись unlock-токена в BLE characteristic class ScooterUnlockManager(private val context: Context) { private var gatt: BluetoothGatt? = null suspend fun unlock(address: String, token: UnlockToken): UnlockResult { return suspendCancellableCoroutine { cont -> val device = bluetoothAdapter.getRemoteDevice(address) gatt = device.connectGatt(context, false, object : BluetoothGattCallback() { override fun onConnectionStateChange(g: BluetoothGatt, status: Int, state: Int) { if (state == BluetoothProfile.STATE_CONNECTED) g.discoverServices() else if (status != BluetoothGatt.GATT_SUCCESS) { cont.resume(UnlockResult.BleConnectionFailed(status)) } } override fun onServicesDiscovered(g: BluetoothGatt, status: Int) { val characteristic = g .getService(token.serviceUUID) ?.getCharacteristic(token.characteristicUUID) ?: run { cont.resume(UnlockResult.ServiceNotFound); return } characteristic.value = token.payload.toByteArray() characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT g.writeCharacteristic(characteristic) } override fun onCharacteristicWrite(g: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) { val result = if (status == BluetoothGatt.GATT_SUCCESS) UnlockResult.Success else UnlockResult.WriteFailed(status) cont.resume(result) g.disconnect() } }, BluetoothDevice.TRANSPORT_LE) cont.invokeOnCancellation { gatt?.disconnect() } } } } —ללא דגל זה, Android עלול לנסות להתחבר דרך Bluetooth קלאסי, מה שיגרום ל-TRANSPORT_LE במכשירים התומכים ב-BLE בלבד.

בעיות בתנאים אמיתיים

אות BLE חלש. הקורקינט נמצא בחניון תת-קרקעי, מוקף ב-20 קורקינטים אחרים עם אותם שירותי GATT. אנו לא סורקים את כל המכשירים ללא הבחנה; אנו מתחברים ישירות: connectGatt באמצעות ה-MAC מתגובת השרת. זה מהיר יותר מאשר סריקת הסביבה.

טוקן שפג תוקף. המשתמש סרק את ה-QR, ואז הוסח דעתו למשך 2 דקות. הטוקן פג תוקף. בעת קבלת status=133 בכתיבה, אך הקורקינט לא נפתח—אנו זקוקים ל-Notify Characteristic לתגובת הבקר. הבקר כותב בחזרה: bluetoothAdapter.getRemoteDevice(address) (OK), GATT_SUCCESS (טוקן פג תוקף), 0x01 (כבר נעול על ידי סשן אחר).

הרשאות Bluetooth ב-Android 12+. 0x02 ו-0x03 הן כעת הרשאות זמן ריצה. אם המשתמש דחה ובחר 'אל תשאל שוב', BLUETOOTH_SCAN מחזיר BLUETOOTH_CONNECT—אנו מובילים אותו להגדרות דרך shouldShowRequestPermissionRationale.

פרטי UX שעושים את ההבדל

הפעלה מקבילה של שרת ו-BLE: ברגע שמתקבלת תגובת השרת עם כתובת המכשיר, אנו מתחילים בחיבור BLE מבלי לחכות לאנימציית ה-UI הסופית. המשתמש רואה ספינר, אבל לחיצת היד של BLE כבר מתרחשת. חוסך כ-300-500 אלפיות שנייה. כדאי גם לשמור טוקנים במטמון: אם הקורקינט היה מחובר בעבר, אנו יכולים לנסות לשחזר את החיבור ללא סריקת QR חוזרת. זה מפחית את זמן הפתיחה הממוצע ב-20-30%.

השוואת גישות פתיחה

מאפיין BLE NFC QR + BLE
מהירות 1-2 שניות 0.5 שניות 1-3 שניות
אבטחה טוקן HMAC מפתח הצפנה טוקן + HMAC
תאימות iOS/Android iPhone 7+, Android 5+ כמעט כל הסמארטפונים
חומרה נוספת אין מודול NFC BLE בלבד
אמינות ברעש בינונית (חיבור לפי כתובת) גבוהה גבוהה (לפי כתובת)

בהתבסס על מחקר מ-Bluetooth SIG ו-תיעוד Apple Core Bluetooth.

טעויות נפוצות ביישום פתיחת BLE

טעות תוצאה פתרון
חסר false שגיאת חיבור ב-Android ציין את הפרמטר במפורש
בקשות בו-זמנית ממספר מכשירים התנגשות טוקנים הזמן קורקינט בשרת
חוסר בהודעות לאחר כתיבה לא ניתן לדעת את התוצאה השתמש ב-Notify characteristic
טוקן ללא חותמת זמן אפשרות לשימוש חוזר HMAC עם חותמת זמן

מה כוללת העבודה

  • מודול סריקת QR ל-iOS ו-Android (ML Kit / AVFoundation)
  • פקודת פתיחת BLE עם תמיכה בפרופיל GATT
  • שירות backend לאימות והזמנה
  • בדיקות על קורקינטים אמיתיים (Nordic nRF52, ESP32)
  • תיעוד אינטגרציה והדרכת צוות

לוחות זמנים ועלות

פיתוח מודול סריקת QR + פתיחת BLE לפלטפורמת שיתוף (iOS + Android): 3-5 שבועות. עם backend מלא לצי (הזמנה, חיוב, גיאו-גידור): 3-5 חודשים. העלות מתחילה מ-$15,000 עבור מודול הפתיחה בלבד, בדרך כלל $25,000–$50,000 עבור אינטגרציה מלאה בהתאם למורכבות. צור איתנו קשר לייעוץ—נספק הצעת מחיר מפורטת תוך יום עסקים אחד.

שלבי יישום

  1. בדיקת חומרת הקורקינט הנוכחית (מודול BLE, קושחה)
  2. עיצוב פרופיל GATT ופרוטוקול
  3. פיתוח מודול iOS (Swift, Combine)
  4. פיתוח מודול Android (Kotlin, Coroutines)
  5. אינטגרציה עם שרת (REST/GraphQL)
  6. בדיקות (יחידה, אינטגרציה, שטח)
  7. פריסה ל-App Store ו-Google Play
  8. ניטור ותמיכה לאחר ההשקה

עם ניסיון של למעלה מ-5 שנים ו-10+ פרויקטים מוצלחים, אנו מבטיחים פתרון חזק ומאובטח. אנו מספקים אחריות ל-12 חודשים על כל הקוד ותיעוד מלא. הערך את הפרויקט שלך תוך יום עסקים אחד. קבל ייעוץ עכשיו—כתוב לנו!