2、Android蓝牙开发环境搭建:Android Studio配置、SDK版本选择、权限声明与真机调试
好,咱们正式开始动手了。这一章我带你把开发环境搭起来。别小看这一步,我见过太多人代码写好了,结果编译不过、权限报错、真机连不上——全是环境问题。咱们一次搞定,后面就顺畅了。
2.1 Android Studio配置:版本与插件
先说IDE。我个人习惯用最新稳定版的Android Studio。目前推荐Arctic Fox或更高版本。为什么?因为蓝牙开发经常要调试低功耗蓝牙(BLE),新版本的Logcat过滤和蓝牙模拟器支持更好。
你打开Android Studio后,记得检查这几个地方:
- SDK Manager:确保安装了Android 10(API 29)及以上的SDK。我建议至少装到API 33,因为蓝牙权限在Android 12、13上有大变化。
- SDK Tools:勾选"Android SDK Build-Tools"和"Android Emulator"。虽然真机调试为主,但偶尔用模拟器跑跑UI还是方便的。
- 插件:我个人会装一个"ADB WIFI"插件,方便无线调试。后面真机调试部分我会细说。
小技巧: 如果你电脑配置一般,可以在gradle.properties里加上
org.gradle.jvmargs=-Xmx2048m,编译速度能快不少。我当年用一台4G内存的老笔记本做蓝牙项目,不加这个参数编译一次要5分钟,加了之后降到2分钟。
2.2 SDK版本选择:别踩这个坑
SDK版本选不对,后面全是坑。我直接给你结论:
| 场景 | minSdkVersion | targetSdkVersion | compileSdkVersion |
|---|---|---|---|
| 经典蓝牙(SPP) | 18(Android 4.3) | 30或31 | 33 |
| 低功耗蓝牙(BLE) | 21(Android 5.0) | 31或32 | 33 |
| 需要位置权限的场景 | 23(Android 6.0) | 31 | 33 |
为什么这么选?我解释一下:
- minSdkVersion:BLE从API 18开始支持,但API 21才稳定。我建议BLE项目直接设21,省得处理各种兼容性问题。
- targetSdkVersion:这个最要命。Android 12(API 31)开始,蓝牙扫描需要
BLUETOOTH_SCAN权限。如果你target设到31以上但没声明这个权限,扫描直接返回空。我曾经帮一个学员排查了两天,最后发现就是target设了32但权限没加。 - compileSdkVersion:尽量用最新的。不影响运行,但能让你用最新的API。
注意: 如果你的targetSdkVersion >= 31,必须使用
BluetoothAdapter.getBluetoothLeScanner()来扫描BLE设备。老方法startLeScan()在API 21就标记为废弃了,但在高版本上直接不能用。
2.3 权限声明:一个都不能少
蓝牙权限声明,说白了就是三件套:
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Android 6.0+ 需要位置权限才能扫描 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 或者 ACCESS_COARSE_LOCATION,但建议用 FINE -->
<!-- Android 12+ 新增的细粒度权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
嗯,这里要注意:
- BLUETOOTH:基础权限,用于连接、通信。没有它,你连打开蓝牙都做不到。
- BLUETOOTH_ADMIN:用于扫描设备、修改蓝牙设置。说白了就是管理权限。
- ACCESS_FINE_LOCATION:这个最坑。Android 6.0到11之间,扫描蓝牙设备必须要有位置权限。为什么?因为蓝牙信号可以用来定位。我当年做室内定位项目时,用户死活不给位置权限,蓝牙扫描就是空的。
- BLUETOOTH_SCAN / BLUETOOTH_CONNECT:Android 12开始,Google终于把蓝牙权限从位置权限里解耦了。但注意,这两个是运行时权限,需要动态申请。
核心原则: 如果你的targetSdkVersion <= 30,只需要BLUETOOTH、BLUETOOTH_ADMIN和ACCESS_FINE_LOCATION。如果target >= 31,必须加上BLUETOOTH_SCAN和BLUETOOTH_CONNECT,并且位置权限可以不加(但部分国产ROM仍然要求)。
2.4 动态权限申请:代码怎么写
光在Manifest里声明不够,运行时还得申请。我直接给你一个模板:
// 检查并请求权限
private void checkBluetoothPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Android 12+
if (checkSelfPermission(Manifest.permission.BLUETOOTH_SCAN)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(
new String[]{
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT
},
REQUEST_CODE_BLUETOOTH_PERMISSIONS
);
}
} else {
// Android 6.0 - 11
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_LOCATION_PERMISSIONS
);
}
}
}
你想想看,为什么分两个版本?因为Android 12之后,Google推荐用新的蓝牙权限替代位置权限。但如果你只加新权限,在Android 11手机上会直接崩溃——因为系统不认识这个权限。
避坑指南: 我曾经遇到一个情况,在小米手机上,即使targetSdkVersion设了31,也申请了BLUETOOTH_SCAN,但扫描还是返回空。后来发现小米的MIUI在Android 12上仍然要求位置权限。所以我的建议是:新老权限都申请,系统会自动忽略不认识的权限。
2.5 真机调试注意事项
模拟器调试蓝牙?别想了。蓝牙硬件在模拟器上基本不可用。你必须用真机。这里我总结几个血泪教训:
- 开启开发者选项:设置 -> 关于手机 -> 连续点击"版本号"7次。这个不用我多说了吧。
- 开启USB调试:开发者选项里找到"USB调试",打开。
- 关闭"监控ADB安装应用":这个选项在部分手机上默认开启,会导致你每次安装都弹窗确认,烦得很。
- 使用无线调试:我强烈推荐。插着USB线调试蓝牙,线会碍事。方法:先USB连接一次,然后在终端执行
adb tcpip 5555,拔掉线,再执行adb connect 手机IP:5555。之后就可以无线调试了。
重要提醒: 真机调试时,记得在开发者选项里关闭"启用MIUI优化"(小米手机)或类似选项。否则蓝牙扫描的回调可能不会触发。我当年排查这个问题花了整整一个下午。
还有一个细节:不同厂商的蓝牙实现有差异。华为手机扫描BLE设备时,如果设备没有广播,可能搜不到。三星手机则对蓝牙连接数有限制。我的建议是:准备两台不同品牌的测试机,一台作为开发机,一台作为目标设备。这样能覆盖大部分兼容性问题。
好了,环境搭建就这些。你按这个步骤走,应该不会出大问题。下一章我们开始写真正的蓝牙代码——扫描设备。到时候你会发现,环境搭好了,后面就是水到渠成的事。