原文网址:http://www.ifeegoo.com/android-turn-on-and-turn-off-bluetooth.html
摘要:Android 中打开和关闭 Bluetooth 的代码虽然并不困难,但是我们还是需要注意一些细节和异常情况,这样我们才能更好的优化我们的与 Bluetooth 相关的应用。
Runtime Environment
OS: Windows 8.1
IDE: ADT Bundle v22.6.2
Device:
Nexus 5 / Android 4.4.4
MI 2SC / MIUI-4.7.11 (Android 4.1.1 JRO03L)
Android 中打开和关闭 Bluetooth 的代码虽然并不困难,但是我们还是需要注意一些细节和异常情况,这样我们才能更好的优化我们的与 Bluetooth 相关的应用。
在研究打开和关闭 Bluetooth 之前,我们应该了解 Android 版本和 Bluetooth 版本之间的关系,请参考本博客文章 《Android 版本与 Bluetooth 版本之间的关系》。
Android 在 Android 2.0 Eclair / API Level 5 中就已经有开放的操作 Bluetooth 的 API 了,在此版本已经有以下公开类:
2 |
* 本地 Bluetooth 适配器,执行基本的 Bluetooth 任务,例如:初始设备扫描、查询已经绑定 |
3 |
* (或已经配对)的设备、通过已知的 MAC 地址来实例化 BluetoothDevice 对象、创建 |
4 |
* BluetoothServerSocket 来监听其它设备的连接请求等。 |
9 |
* 描述设备的一般特性和能力。例如,它会指定一般设备类型,例如:手机、电脑、耳机等,还 |
10 |
* 有是否支持音频或电话等服务。但是不能可靠的描述诸如设备支持哪些 Profile 或者 Service。 |
15 |
* 表示一个远程的 Bluetooth 设备。它能让你与各个设备创建连接或者查询信息。 |
21 |
* Bluetooth socket 和 TCP socket 有些类似。最普通的 Bluetooth socket 类型是 RFCOMM, |
22 |
* 这是 Android API 支持的类型。RFCOMM 是一个方向性的连接。通过 Bluetooth 传输流。 |
23 |
* 同样也称作 SPP (Serial Port Profile)。 |
25 |
BluetoothServerSocket.java |
Android 中打开 Bluetooth:有以下三种方法:
1.强制打开
2.调用系统弹出框提示用户打开
3.跳转到系统设置中让用户自己打开
1.强制打开 Bluetooth 的代码:
1 |
BluetoothAdapter.getDefaultAdapter() 需要注册权限: |
2 |
<uses-permission android:name= "android.permission.BLUETOOTH" /> |
4 |
BluetoothAdapter.enable() 需要注册权限: |
5 |
<uses-permission android:name= "android.permission.BLUETOOTH_ADMIN" /> |
4 |
* @author ifeegoo www.ifeegoo.com |
7 |
public class BluetoothManager |
11 |
* 当前 Android 设备是否支持 Bluetooth |
13 |
* @return true:支持 Bluetooth false:不支持 Bluetooth |
15 |
public static boolean isBluetoothSupported() |
17 |
return BluetoothAdapter.getDefaultAdapter() != null ? true : false ; |
21 |
* 当前 Android 设备的 bluetooth 是否已经开启 |
23 |
* @return true:Bluetooth 已经开启 false:Bluetooth 未开启 |
25 |
public static boolean isBluetoothEnabled() |
27 |
BluetoothAdapter bluetoothAdapter = BluetoothAdapter |
30 |
if (bluetoothAdapter != null ) |
32 |
return bluetoothAdapter.isEnabled(); |
39 |
* 强制开启当前 Android 设备的 Bluetooth |
41 |
* @return true:强制打开 Bluetooth 成功 false:强制打开 Bluetooth 失败 |
43 |
public static boolean turnOnBluetooth() |
45 |
BluetoothAdapter bluetoothAdapter = BluetoothAdapter |
48 |
if (bluetoothAdapter != null ) |
50 |
return bluetoothAdapter.enable(); |
以上强制打开 Bluetooth 是调用了 BluetoothAdapter.enable() 方法。首先需要获取 BluetoothAdapter 对象,如果这个对象为 null 的话,说明当前设备不支持 Bluetooth 功能。还有以下几点需要注意:
1° 在 Nexus 5 Android 4.4.4 原生系统中,在没有任何其它管理 Bluetooth 权限的应用情况下,调用强制打开 Bluetooth 的方法,没有任何提示就直接打开 Bluetooth 了。
2° 在小米手机 MI 2SC / MIUI-4.7.11 (Android 4.1.1 JRO03L) 上系统自带的 “安全中心” – “应用权限管理” – “开启蓝牙” 中,有三种设置:
允许:调用强制打开 Bluetooth 代码,没有任何提示,Bluetooth 被成功打开。
提示:会弹出提示框,提示安全警告 “ ***应用尝试开启蓝牙”,可以选择“拒绝”或“允许”,还有记住此次选择(备注:如果不记住的话,下次还会弹出同样的提示框,除非你自己去修改了应用开启蓝牙的权限)。
拒绝:调用强制打开 Bluetooth 代码,没有任何提示,Bluetooth 强制打开失败。
备注:各种手机自带的权限管理功能或者第三方权限管理应用略有不同。
3° 对于 BluetoothAdapter.enable() 这个方法,API 中有以下说明 (备注:初始 API 中,如 Android 2.0 Eclair / API Level 5 中并没有这段提示)
Bluetooth should never be enabled without direct user consent. If you want to turn on Bluetooth in order to create a wireless connection, you should use the ACTION_REQUEST_ENABLE Intent, which will raise a dialog that requests user permission to turn on Bluetooth. The enable() method is provided only for applications that include a user interface for changing system settings, such as a “power manager” app.
没有直接的用户的允许绝不要开启 Bluetooth。如果你想要打开 Bluetooth 创建一个无线连接,你应当使用 ACTION_REQUEST_ENABLE Intent,这样会弹出一个提示框提示用户是否开启 Bluetooth,enable() 方法仅提供给有 UI 、更改系统设置的应用来使用,例如“电源管理”应用。
从以上官方 API 提示可以看出:不建议你调用此方法来打开 Bluetooth,至少是在没有任何用户提醒的前提下!


2.调用系统弹出框提示用户打开:
1 |
this .startActivityForResult(requestBluetoothOn, REQUEST_CODE_BLUETOOTH_ON) 需要注册权限: |
2 |
<uses-permission android:name= "android.permission.BLUETOOTH" /> |
1 |
public class MainActivity extends Activity |
4 |
* 自定义的打开 Bluetooth 的请求码,与 onActivityResult 中返回的 requestCode 匹配。 |
6 |
private static final int REQUEST_CODE_BLUETOOTH_ON = 1313 ; |
9 |
* Bluetooth 设备可见时间,单位:秒。 |
11 |
private static final int BLUETOOTH_DISCOVERABLE_DURATION = 250 ; |
14 |
protected void onCreate(Bundle savedInstanceState) |
16 |
super .onCreate(savedInstanceState); |
17 |
this .setContentView(R.layout.activity_main); |
19 |
if ((BluetoothManager.isBluetoothSupported()) |
20 |
&& (!BluetoothManager.isBluetoothEnabled())) |
22 |
this .turnOnBluetooth(); |
27 |
* 弹出系统弹框提示用户打开 Bluetooth |
29 |
private void turnOnBluetooth() |
32 |
Intent requestBluetoothOn = new Intent( |
33 |
BluetoothAdapter.ACTION_REQUEST_ENABLE); |
35 |
// 设置 Bluetooth 设备可以被其它 Bluetooth 设备扫描到 |
37 |
.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); |
39 |
// 设置 Bluetooth 设备可见时间 |
40 |
requestBluetoothOn.putExtra( |
41 |
BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, |
42 |
BLUETOOTH_DISCOVERABLE_DURATION); |
45 |
this .startActivityForResult(requestBluetoothOn, |
46 |
REQUEST_CODE_BLUETOOTH_ON); |
50 |
protected void onActivityResult( int requestCode, int resultCode, Intent data) |
52 |
// requestCode 与请求开启 Bluetooth 传入的 requestCode 相对应 |
53 |
if (requestCode == REQUEST_CODE_BLUETOOTH_ON) |
58 |
case Activity.RESULT_OK: |
60 |
// TODO 用户选择开启 Bluetooth,Bluetooth 会被开启 |
65 |
case Activity.RESULT_CANCELED: |
67 |
// TODO 用户拒绝打开 Bluetooth, Bluetooth 不会被开启 |
对于以上弹出系统弹框提示用户打开 Bluetooth 的代码,有以下几点需要注意:
1° 这种调用系统的弹出框提示用户打开 Bluetooth 的方式,一般不会受到系统或者第三方权限管理应用的阻止。只有当你不提示用户的情况下,可以理解为“偷偷摸摸”的打开 Bluetooth ,这个是被认为侵犯用户的知情权,系统或者第三方权限管理应用可能加以阻止:直接禁止不提示用户的情况下打开 Bluetooth,或者提示用户,又或者是让用户自己选择哪些应用可以强制开启 Bluetooth。而在 Nexus 5 / Android 4.4.4 原生系统强制打开 Bluetooth 是没有任何提示,并且可以成功打开。
2° 弹出系统的提示框提醒用户打开 Bluetooth 的主要代码:
this.startActivityForResult(requestBluetoothOn,REQUEST_CODE_BLUETOOTH_ON);
注意:这个方法是需要 Activity 的对象来调用的!并且需要在 Activity 中重写 onActivityResult 方法来获取用户操作弹出提示框的结果!
3° 这种弹出的系统弹框,根据系统的不同,UI 会有所不同,下图左边是 Nexus 5 Android 4.4.4 系统手机显示效果,右边是小米手机 MI 2SC / MIUI-4.7.11 (Android 4.1.1 JRO03L) 系统显示的效果:

4° 如果你只设置了 Bluetooth 设备的可见时间,而不去调用 setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE) 方法的话,Bluetooth 依然是不可见的。你设置的 Bluetooth 的可见时间是不生效的,当前 Android 系统的 Bluetooth 不可见!
5° 设置 Bluetooth 设备的可见时间的时候,在 Android 4.4.2 官方 API 中的说明如下:
The current default is 120 seconds, and requests over 300 seconds will be capped. These values could change.
当前默认值是 120s ,300s 是上限。这些值可能会变。
目前测试出来的有以下结论:
— 可设置的可见时间为 [1,3600] s ,也就是最小1秒钟,最大1个小时。
— 设置的可见时间为 0 时,表示打开 Bluetooth 之后一直可见,设置小于0或者大于3600 时,系统会默认为 120s。
6° 如果你设备的 Bluetooth 已经打开,而且你不设置设备的可见时间的话,调用以上开启 Bluetooth 的方法,是不会有任何提示的。当然,如果 Bluetooth 已经开启,也可以通过这个方法来修改 Bluetooth 的可见性。
3.跳转到系统设置中让用户自己打开:
2 |
this .startActivity( new Intent(Settings.ACTION_BLUETOOTH_SETTINGS)); |
考虑到涉及用户隐私和用户体验,推荐以下方式开启 Bluetooth :
1° 采用强制开启 Bluetooth 的方式打开 Bluetooth ,但是调用强制开启 Bluetooth 代码之前,我们自己在应用中提示用户,我们的应用需要开启 Bluetooth ,让用户自己选择是否开启 Bluetooth 。自己在应用中提示用户我们需要开启 Bluetooth 相对于弹出系统的提示框提示用户当前应用需要开启 Bluetooth 的优势在于我们可以控制提示的内容和提示的方式以及 UI。
2° 假若用户选择了开启 Bluetooth,但是强制开启 Bluetooth 失败,比如系统自带的权限管理禁止你的应用开启 Bluetooth ,我们不去提示用户说当前系统禁止了应用开启 Bluetooth,让用户自己去解除禁止。这样显然用户体验很差。这种情况下,我们再去调用弹出系统提示框提醒用户打开 Bluetooth 即可。这种方式一般系统或者第三方应用不会禁止。
3° 如果弹出系统提示框提醒用户打开 Bluetooth 有问题的话,最后采用提示用户自己去系统 Bluetooth 设置中打开 Bluetooth,跳转到系统的 Bluetooth 设置界面。
Android 中关闭 Bluetooth:有以下俩种方法:
1.强制关闭
2.跳转到系统设置中让用户自己关闭
1.强制关闭:
1 |
BluetoothAdapter.getDefaultAdapter() 需要注册权限: |
2 |
<uses-permission android:name= "android.permission.BLUETOOTH" /> |
4 |
BluetoothAdapter.disable() 需要注册权限: |
5 |
<uses-permission android:name= "android.permission.BLUETOOTH_ADMIN" /> |
4 |
* @author ifeegoo www.ifeegoo.com |
7 |
public class BluetoothManager |
10 |
* 当前 Android 设备是否支持 Bluetooth |
12 |
* @return true:支持 Bluetooth false:不支持 Bluetooth |
14 |
public static boolean isBluetoothSupported() |
16 |
return BluetoothAdapter.getDefaultAdapter() != null ? true : false ; |
20 |
* 当前 Android 设备的 bluetooth 是否已经开启 |
22 |
* @return true:Bluetooth 已经开启 false:Bluetooth 未开启 |
24 |
public static boolean isBluetoothEnabled() |
26 |
BluetoothAdapter bluetoothAdapter = BluetoothAdapter |
29 |
if (bluetoothAdapter != null ) |
31 |
return bluetoothAdapter.isEnabled(); |
38 |
* 强制开启当前 Android 设备的 Bluetooth |
40 |
* @return true:强制打开 Bluetooth 成功 false:强制打开 Bluetooth 失败 |
42 |
public static boolean turnOnBluetooth() |
44 |
BluetoothAdapter bluetoothAdapter = BluetoothAdapter |
47 |
if (bluetoothAdapter != null ) |
49 |
return bluetoothAdapter.enable(); |
56 |
* 强制关闭当前 Android 设备的 Bluetooth |
58 |
* @return true:强制关闭 Bluetooth 成功 false:强制关闭 Bluetooth 失败 |
60 |
public static boolean turnOffBluetooth() |
62 |
BluetoothAdapter bluetoothAdapter = BluetoothAdapter |
65 |
if (bluetoothAdapter != null ) |
67 |
return bluetoothAdapter.disable(); |
以上强制关闭 Bluetooth 是调用了 BluetoothAdapter.disable() 方法。首先需要获取 BluetoothAdapter 对象,如果这个对象为 null 的话,说明当前设备不支持 Bluetooth 功能。还有以下几点需要注意:
1° 目前发现常见的系统或者第三方权限管理应用好像对关闭 Bluetooth 并不做限制。
2° 如果系统或者第三方权限管理应用限制你的应用关闭 Bluetooth 的话,请参考强制开启 Bluetooth 要注意的点 1° 和 2°。
3° 对于 BluetoothAdapter.disable() 这个方法,API 中有以下说明 (备注:初始 API 中,如 Android 2.0 Eclair / API Level 5 中并没有这段提示)
Bluetooth should never be disabled without direct user consent. The disable() method is provided only for applications that include a user interface for changing system settings, such as a “power manager” app.
没有直接的用户的允许绝不要关闭 Bluetooth。disable() 方法仅提供给有 UI 、更改系统设置的应用来使用,例如“电源管理”应用。
从以上官方 API 提示可以看出:不建议你调用此方法来关闭 Bluetooth,至少是在没有任何用户提醒的前提下!
2.跳转到系统设置中让用户自己关闭:
2 |
this .startActivity( new Intent(Settings.ACTION_BLUETOOTH_SETTINGS)); |
考虑到涉及用户隐私和用户体验,推荐以下方式关闭 Bluetooth :
1° 采用强制关闭 Bluetooth 的方式关闭 Bluetooth ,但是调用强制关闭 Bluetooth 代码之前,我们自己在应用中提示用户,我们的应用需要关闭 Bluetooth ,让用户自己选择是否关闭 Bluetooth 。自己在应用中提示用户我们需要关闭 Bluetooth ,暂时没有发现 Android 有提供了弹出系统提示框提示用户关闭 Bluetooth 的 API。
2° 假若用户选择了关闭 Bluetooth,但是强制关闭 Bluetooth 失败,比如系统自带的权限管理禁止你的应用关闭 Bluetooth ,我们不去提示用户说当前系统禁止了应用关闭 Bluetooth,让用户自己去解除禁止。这样显然用户体验很差。这种情况下,我们提示用户“由于某些原因导致应用关闭 Bluetooth 失败,请到系统设置中自己关闭 Bluetooth”,然后跳转到系统 Bluetooth 设置中。
- android 输入法的打开和关闭
一.打开输入法窗口: InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.IN ...
- Android 监听 Android中监听系统网络连接打开或者关闭的实现代码
本篇文章对Android中监听系统网络连接打开或者关闭的实现用实例进行了介绍.需要的朋友参考下 很简单,所以直接看代码 复制代码 代码如下: package xxx; import android.c ...
- Android系统移植与调试之------->增加一个双击物理按键打开和关闭闪光灯并将闪光灯状态同步到下拉菜单中
最近有一个客户有这样的需求: 1.在[设置]--->[无障碍]中添加一个开关按钮. 如果打开开关的话,双击某个物理按键的时候,打开闪光灯,再双击该物理按键的时候,关闭闪光灯. 如果关闭开关的话, ...
- 如何取消android studio启动时自动打开上次关闭的项目
Androidstudio默认每次android studio启动就会自动打开上次关闭的项目,如果想要取消并让它显示此界面 只需要
- 用Android程序打开和关闭输入法
一.打开输入法窗体: InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPU ...
- 【转】Android bluetooth介绍(三): 蓝牙扫描(scan)设备分析
原文网址:http://blog.csdn.net/xubin341719/article/details/38584469 关键词:蓝牙blueZ A2DP.SINK.sink_connect.s ...
- android Bluetooth(官方翻译)
Bluetooth Using the Bluetooth APIs, an Android application can perform the following: 使用蓝牙APIs,一个And ...
- Android Bluetooth开发
原文地址:http://developer.android.com/guide/topics/wireless/bluetooth.html 翻译:jykenan 更新:2012.06.19 Andr ...
- Android BLE与终端通信(二)——Android Bluetooth基础科普以及搜索蓝牙设备显示列表
Android BLE与终端通信(二)--Android Bluetooth基础搜索蓝牙设备显示列表 摘要 第一篇算是个热身,这一片开始来写些硬菜了,这篇就是实际和蓝牙打交道了,所以要用到真机调试哟, ...
随机推荐
- sql like '%x%'优化
好久没写点什么了.唉(此处省略无数,一切尽在苦逼中...) 说说sql中的全匹配优化吧.在sql server进行模糊查询的时候,如果是进行全匹配的话,那么肯定会用到like.我们知道like '%张 ...
- ajax 基础教程
这是一本什么书?这是一本技术类的书籍,主要从历史.XMLHttpRequest对象.怎么样于服务器交互.构建完备的Ajax开发工具箱.使用jsUnit测试javascript 代码,总之就是让我们从这 ...
- 前台研发工具Sublime
沟通交流群 [极客Online : 546653637] 欢迎您! 今天一个朋友@我,问有没有好的IDE推荐一下,其实现在有很多文本工具可供选择,像Nodepad++.Editplus之类的,之前我使 ...
- Spring处理id相同的bean
http://www.360doc.com/content/13/1018/05/41237_322247510.shtml(应该可以解决) http://www.2cto.com/kf/201601 ...
- 4 C#和Java 的比较
2007年11月1日 1.访问控制方面:C#有public.internal.protected.private,比java多了个internal,其实它跟java的包访问差不多,interna ...
- C#的输入输出流
一 .NET Framework 类库的System.IO 命名空间 System.IO 命名空间包含允许读写文件和数据流的类型以及提供基本文件和目录支持的类型. 二 C#文件读写之Fi ...
- C# 之【线程与进程】
1. 引言 先来个比喻手法: 如果把上课的过程比作进程,那么每个学生就是一个线程,他们共享教室,即线程共享进程的内存空间.每一个时刻,只能一个学生问老师问题,老师回答完毕,轮到下一个.即线程在一个时 ...
- js原型解析
我们都知道javascript因为具有了继承以及变量等等一系列的特性之后才被人们认为具有一门编程语言的资格,在后续的不断发展中,js在原生的基础上扩展了基于jquery等等的库,甚至衍生了像node. ...
- 也谈Excel导出
吐槽 Excel导出在天朝的软件大环境下,差点成为软件开发必备.俺就遇到过,所有报表不提供导出功能,就能不验收的囧事.报表能查看能打印能形成图表已经完美,实在搞不懂导出excel有个毛用,但是公司依靠 ...
- 我的Hibernate入门
今天忙了一整天,终于搭建好了我的第一个Hibernate程序,中间关于hibernate.cfg.xml的问题搞了半天,不过最后还是搞明白了,下面来讲一讲过程. 首先在你的eclipse中安装Hibe ...