Skip to main content

Bike Sharing Guide

Simple guide for implementing bike sharing functionality using the MOSA SDK. This guide focuses on SDK method calls from the mobile app's perspective.

Overview​

Bike sharing allows users to rent bikes from sharing stations and return them later. The flow involves:

  1. Renting: User unlocks a bike from a sharing station
  2. Returning: User locks the bike back at a sharing station

Renting a Bike​

Step 1: Request Unlock Key​

Request a rentBikeUnlock key for the sharing area:

lifecycleScope.launch {
val unlockKey = sdk.requestUnlockKey(
type = MOSADockUnlockKeyType.RentBikeUnlock,
areaId = "area-123"
)

if (unlockKey != null) {
rentBike(unlockKey)
}
}

Step 2: Execute Unlock Operation​

Call unlockSmartLock() with the unlock key and sharing location type:

private fun rentBike(unlockKey: MOSADockKey) {
lifecycleScope.launch {
sdk.unlockSmartLock(
unlockKey = unlockKey,
gfaLocationType = MOSADockLocationType.SHARING,
callback = object : MOSADockSDKCallback {
override fun onNFCScanCompleted(mosaTag: MosaTag) {
// NFC scan completed
}

override fun onBleConnecting() {
// BLE connecting
}

override fun onBleConnected() {
// BLE connected
}

override fun onKeySent() {
// Key sent to dock
}

override fun onDockUnlocked() {
// Dock unlocked
}

override fun onDockChainRemoved() {
// Chain removed - bike ready to take, start rental timer
}

override fun onError(error: MosaError) {
// Handle error
}

// Implement other callbacks...
}
)
}
}

Callback Sequence for Renting​

The expected callback sequence:

  1. onNFCScanCompleted - NFC tag read
  2. onBleConnecting - BLE connection started
  3. onBleConnected - BLE connected
  4. onKeySent - Unlock key sent to dock
  5. onDockUnlocked - Dock unlocked
  6. onDockChainRemoved - Chain removed (bike ready to take, start rental timer)

Returning a Bike​

Step 1: Request Lock Key​

Request a rentBikeLock key. The SDK uses the existing session from the previous unlock operation:

lifecycleScope.launch {
val unlockKey = sdk.requestUnlockKey(
type = MOSADockUnlockKeyType.RentBikeLock,
areaId = "area-123" // areaId from session
)

if (unlockKey != null) {
returnBike(unlockKey)
}
}

Step 2: Execute Lock Operation​

Call unlockSmartLock() with the lock key and sharing location type:

private fun returnBike(unlockKey: MOSADockKey) {
lifecycleScope.launch {
sdk.unlockSmartLock(
unlockKey = unlockKey,
gfaLocationType = MOSADockLocationType.SHARING,
callback = object : MOSADockSDKCallback {
override fun onNFCScanCompleted(mosaTag: MosaTag) {
// NFC scan completed
}

override fun onBleConnecting() {
// BLE connecting
}

override fun onBleConnected() {
// BLE connected
}

override fun onKeySent() {
// Key sent to dock
}

override fun onDockUnlocked() {
// Dock unlocked
}

override fun onDockChainInserted() {
// Chain inserted - bike locked, stop rental timer
}

override fun onDockSecured() {
// Dock secured - rental complete
}

override fun onError(error: MosaError) {
// Handle error
}

// Implement other callbacks...
}
)
}
}

Callback Sequence for Returning​

The expected callback sequence:

  1. onNFCScanCompleted - NFC tag read
  2. onBleConnecting - BLE connection started
  3. onBleConnected - BLE connected
  4. onKeySent - Lock key sent to dock
  5. onDockUnlocked - Dock unlocked
  6. onDockChainInserted - Chain inserted (bike locked, stop rental timer)
  7. onDockSecured - Dock secured (rental complete)

Complete Example​

Here's a complete example combining both operations:

class BikeSharingActivity : AppCompatActivity(), MOSADockSDKCallback {
private lateinit var sdk: MOSADockSDK
private var rentalStartTime: Long? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

sdk = MOSADockSDK.builder()
.setActivity(this)
.setApiKey("your-api-key")
.setUserId("user-123")
.build()
}

fun rentBike() {
lifecycleScope.launch {
val unlockKey = sdk.requestUnlockKey(
type = MOSADockUnlockKeyType.RentBikeUnlock,
areaId = "area-123"
)

if (unlockKey != null) {
sdk.unlockSmartLock(
unlockKey = unlockKey,
gfaLocationType = MOSADockLocationType.SHARING,
callback = this@BikeSharingActivity
)
}
}
}

fun returnBike() {
lifecycleScope.launch {
val unlockKey = sdk.requestUnlockKey(
type = MOSADockUnlockKeyType.RentBikeLock,
areaId = "area-123"
)

if (unlockKey != null) {
sdk.unlockSmartLock(
unlockKey = unlockKey,
gfaLocationType = MOSADockLocationType.SHARING,
callback = this@BikeSharingActivity
)
}
}
}

override fun onDockChainRemoved() {
// Start rental timer
rentalStartTime = System.currentTimeMillis()
startRentalTimer()
}

override fun onDockSecured() {
// Stop rental timer and calculate rental duration
rentalStartTime?.let { startTime ->
val duration = System.currentTimeMillis() - startTime
endRental(duration)
}
}

// Implement other callbacks...
}

Required Parameters​

Rent Operation​

  • Key Type: rentBikeUnlock
  • Area ID: ID of the sharing area
  • Location Type: SHARING / .sharing / sharing

Return Operation​

  • Key Type: rentBikeLock
  • Area ID: ID of the sharing area (from session)
  • Location Type: SHARING / .sharing / sharing

Rental Timer​

For bike sharing, you should track rental duration:

  • Start Timer: When onDockChainRemoved is called (bike taken)
  • Stop Timer: When onDockSecured is called (bike returned)
  • Display Duration: Show rental duration to user
  • Calculate Fee: Use duration to calculate rental fee (if applicable)

Next Steps​