开发minibeacon bluetooth安卓定位应用求助:如何在代码中配置UUID
Hey there! I’ve worked with Bluetooth beacons on Android before, so let’s break this down into clear, actionable steps and give you code examples to get you up and running.
First, Prep Work You Need to Nail Down
Before writing any code, make sure you have these sorted:
- Grab your Minibeacon's UUID (plus Major/Minor values): Use a Bluetooth debugging app like nRF Connect or the official Minibeacon configuration tool to scan your device. You’ll see its broadcast data, which includes a 16-byte UUID, plus Major and Minor identifiers—jot these down, they’re critical later.
- Set up Android permissions: For Android 12+ (API level 31+), add these to your
AndroidManifest.xmlto enable Bluetooth scanning:
For older Android versions (below 12), swap in<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />BLUETOOTHandBLUETOOTH_ADMINinstead, plusACCESS_COARSE_LOCATIONorACCESS_FINE_LOCATION.
Core Development Steps & Example Code
1. Initialize the Bluetooth Adapter
First, check if Bluetooth is enabled and get the adapter instance:
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothManager import android.content.Context fun getBluetoothAdapter(context: Context): BluetoothAdapter? { val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager return bluetoothManager.adapter }
If the adapter is null or disabled, prompt the user to turn on Bluetooth via an Intent with ACTION_REQUEST_ENABLE.
2. Scan for Your Minibeacon (Filter by UUID)
We’ll use BluetoothLeScanner to scan, and filter results to only pick up your target beacon using its UUID. Here’s a complete Kotlin example:
import android.bluetooth.le.BluetoothLeScanner import android.bluetooth.le.ScanCallback import android.bluetooth.le.ScanResult import android.os.Handler import java.nio.ByteBuffer import java.util.UUID class BeaconScanner(private val context: Context) { private val bluetoothAdapter = getBluetoothAdapter(context) private lateinit var scanner: BluetoothLeScanner private val scanHandler = Handler() private val scanPeriod: Long = 10000 // Scan for 10 seconds at a time // Replace these with YOUR Minibeacon's details! private val TARGET_UUID = "YOUR_MINIBEACON_UUID_HERE" // e.g., "B9407F30-F5F8-466E-AFF9-25556B57FE6D" private val TARGET_MAJOR = 1234 // Replace with your beacon's Major value private val TARGET_MINOR = 5678 // Replace with your beacon's Minor value fun startScanning() { if (bluetoothAdapter?.isEnabled != true) { // Prompt user to enable Bluetooth here return } scanner = bluetoothAdapter.bluetoothLeScanner val scanCallback = object : ScanCallback() { override fun onScanResult(callbackType: Int, result: ScanResult) { super.onScanResult(callbackType, result) parseBeaconData(result) } } // Start scanning scanner.startScan(scanCallback) // Auto-stop after 10 seconds to save battery scanHandler.postDelayed({ scanner.stopScan(scanCallback) }, scanPeriod) } private fun parseBeaconData(result: ScanResult) { val scanRecord = result.scanRecord ?: return val serviceData = scanRecord.serviceData // Minibeacons often use iBeacon format, which uses service UUID 0xFEAA val iBeaconServiceUuid = UUID.fromString("0000feaa-0000-1000-8000-00805f9b34fb") serviceData[iBeaconServiceUuid]?.let { data -> // iBeacon data structure: UUID (16 bytes), Major (2), Minor (2), TxPower (1) if (data.size >= 25) { val uuid = bytesToUuid(data.copyOfRange(4, 20)) val major = (data[20].toInt() shl 8) or (data[21].toInt() and 0xFF) val minor = (data[22].toInt() shl 8) or (data[23].toInt() and 0xFF) // Check if this matches your target beacon if (uuid.toString().equalsIgnoreCase(TARGET_UUID) && major == TARGET_MAJOR && minor == TARGET_MINOR) { val txPower = data[24].toInt() val distance = calculateDistance(txPower, result.rssi) println("Found your Minibeacon! Approx distance: ${"%.2f".format(distance)} meters") // Update your UI here to show the beacon's presence/distance } } } } private fun bytesToUuid(bytes: ByteArray): UUID { val msb = ByteBuffer.wrap(bytes.copyOfRange(0, 8)).long val lsb = ByteBuffer.wrap(bytes.copyOfRange(8, 16)).long return UUID(msb, lsb) } private fun calculateDistance(txPower: Int, rssi: Int): Double { if (rssi == 0) return -1.0 // Can't calculate distance val ratio = rssi.toDouble() / txPower.toDouble() return if (ratio < 1.0) { Math.pow(ratio, 10.0) } else { 0.89976 * Math.pow(ratio, 7.7095) + 0.111 } } }
Key Note on UUID Insertion
Just replace YOUR_MINIBEACON_UUID_HERE with the exact UUID you pulled from your beacon (it’s case-insensitive, but keep the hyphenated format). The Major/Minor values are optional but helpful if you have multiple beacons to distinguish between.
3. Request Runtime Permissions
Don’t forget to ask the user for required permissions before scanning:
import android.app.Activity import android.content.pm.PackageManager import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat private val REQUEST_PERMISSIONS_CODE = 1001 private val REQUIRED_PERMISSIONS = arrayOf( android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.ACCESS_FINE_LOCATION ) fun checkPermissions(activity: Activity) { val permissionsToRequest = REQUIRED_PERMISSIONS.filter { ContextCompat.checkSelfPermission(activity, it) != PackageManager.PERMISSION_GRANTED }.toTypedArray() if (permissionsToRequest.isNotEmpty()) { ActivityCompat.requestPermissions(activity, permissionsToRequest, REQUEST_PERMISSIONS_CODE) } else { // Permissions granted—start scanning! BeaconScanner(activity).startScanning() } }
Debugging Tips
- Verify your Minibeacon is broadcasting first using nRF Connect—if it doesn’t show up there, your app won’t find it either.
- Make sure location services are enabled on the Android device—Bluetooth scanning requires this on most versions.
- Use Logcat to print raw scan results if you’re not seeing your beacon, to confirm your UUID is correct.
Alternative: Use a Beacon Library
If you don’t want to parse beacon data manually, libraries like AltBeacon’s Android Beacon Library simplify scanning and filtering. You just configure your beacon’s UUID in the library setup, and it handles the rest.
内容的提问来源于stack exchange,提问作者Manitra Berthon Raoilison

