Android学习笔记——Bluetooth的使用
蓝牙应该是现在每一部智能手机的标配了。想当年在山寨机横行的年代里,蓝牙都可以做为一个卖点~~~
废话不多说了,进入正题:
使用蓝牙功能是需要权限的,关于蓝牙的权限也就两个:
<uses-permission android:name=”android.permission.BLUETOOTH” /> <uses-permission android:name=”android.permission.BLUETOOTH_ADMIN” />
第一个是最基本的,打开蓝牙,请求连接,接受连接都需要这个。
每二个从字面上看都觉得高级一点,它主要用于像建立搜索、对蓝牙进行设置这些操作。
添加好权限之后就可以开始使用了
Android系统为我们提供了一个功能极其强大的类用于进行蓝牙操作,这个类就是BluetoothAdapter。通过这个类的方法可以满足我们的大多数操作了。
要获得这个类的对象我们可以直接调用它的一个静态方法getDefaultAdapter()。顺便看看它的源码是怎样的吧:
public static synchronized BluetoothAdapter getDefaultAdapter() {
if (sAdapter == null) {
IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
if (b != null) {
IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
sAdapter = new BluetoothAdapter(managerService);
} else {
Log.e(TAG, "Bluetooth binder is null");
}
}
return sAdapter;
}
典型的单例模式:
打开蓝牙
首先要先确实您的设备是否有蓝牙,这个验证还是很有必要的,因为我们要考虑到我们的应用不一定就是给手机用的,也可能是平板之类的。
private boolean isBluetoothAvaliable() {
return BluetoothAdapter.getDefaultAdapter() != null;
}
我们一般打开蓝牙会使用到系统提供的一个Activity。这个Activity的action为:BluetoothAdapter.ACTION_REQUEST_ENABLE。
然后我们要使用startActivityForResult()这个方法来启动它。
这个Activity是有返回值的,如果用户选择的是打开,我们应该可以收到一个RESULT_OK
如果用户选择的是取消,我们应该可以收到一个RESULT_CANCELED。
比如像下面的这一段代码:
public void openBluetooth() {
Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBT, 1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
System.out.println("蓝牙已打开");
} else if (resultCode == RESULT_CANCELED) {
System.out.println("取消打开");
}
}
}
监听蓝牙状态的变化
当蓝牙的状态发生改变时,系统是会发出一个为BluetoothAdapter.ACTION_STATE_CHANGED的广播。
该广播携带两个参数,一个是BluetoothAdapter.EXTRA_PREVIOUS_STATE,表示之前的蓝牙状态。
另一个是BluetoothAdapter.EXTRA_STATE,表示当前的蓝牙状态。而它们的值为以下四个:
BluetoothAdapter.STATE_TURNING_ON;
BluetoothAdapter.STATE_ON;
BluetoothAdapter.STATE_TURNING_OFF;
BluetoothAdapter.STATE_OFF;
分别代表,打开中,已打开,关闭中,已关闭。
private class BluetoothStateListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
String msg = null;
switch (state) {
case BluetoothAdapter.STATE_TURNING_ON:
msg = "turning on";
break;
case BluetoothAdapter.STATE_ON:
msg = "on";
break;
case BluetoothAdapter.STATE_TURNING_OFF:
msg = "turning off";
break;
case BluetoothAdapter.STATE_OFF:
msg = "off";
break;
}
System.out.println(msg);
}
}
protected void onResume() {
super.onResume();
// 蓝牙开闭状态接收器
listener = new BluetoothStateListener();
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(listener, filter);
}
当然在程序中的某刻,我们可以调用BludetoothAdapter的getState()这个方法,该方法的返回值为上面的四个中的一个,不再赘述。
查找蓝牙设备
这个关于查找设备要分为两个部分,一个是已绑定的设备,另一个是搜索新的设备。
对于已绑定的设备,我们可以直接通过BluetoothAdapter的getBondedDevices()这个方法来获得。
该方法返回的是一个Set<BluetoothDevice>我们可以直接从人获得我们需要的信息:
public void getBoundedDevices() {
System.out.println("getPairedDevices");
// 这个要在打开蓝牙的情况下才可以,不然为空集
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> devices = adapter.getBondedDevices();
for (BluetoothDevice device : devices) {
System.out.println(device.getName() + " : " + device.getAddress());
}
}
另外就是查找新的设备了,这时我们要调用startDiscovery()方法,这个方法并不会在我们的程序中执行,它是系统进程来的,然后通过异步发送广播的方式来通知。
所以我们还要注册一个广播接收器来接收系统的广播,这个广播的action为BluetoothDevice.ACTION_FOUND。
它携带两个值,一个是BluetoothDevice.EXTRA_DEVICE另一个是BluetoothDevice.EXTRA_CLASS分别表示哪一个具体的设备和这个设备的类型。
private class BluetoothDeviceScanListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 这里可以把我们的将我们的设备添加到一个列表中
System.out.println(device.getName() + " : " + device.getAddress());
}
}
在官方的文档中一直强调,查找设备这个动作是会消耗大量的系统资源的,而且它会大大减少蓝牙的可用带宽,所以当我们找到了目标设备后,应该由我们主动调用cancelDiscovery()这个方法来取消搜索,而不应该期待默认的搜索时间到了,由系统来取消搜索。
设置可被搜索
蓝牙的默认设置是不允许被搜索到的,这一点有时候挺蛋疼的。
所以我们自己通过编程来实现打开可被搜索的选择,使用是很装简单的,也是调用系统的一个Activity。这个activity的action是BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE它同样是有返回值的。并且,这个我们可以通过BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION这个参数来指定可被搜索的时间。
public void discoverable() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
// 这个可以用来设置时间
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200);
startActivityForResult(intent, 2);
}
这个Activity还同时具有打开蓝牙的功能,所以我们并不需要先打开蓝牙,再设置可被发现的时间,一次就可以搞定。
最后,这个状态的改变系统也是会发出广播的,我们可以注册一个广播接收器来捕捉这个状态的变化,或是通过调用BluetoothAdapter的getScanMod()这个方法来确定,和之前是一样的。不再细说了。
(未定待续)
Android学习笔记——Bluetooth的使用的更多相关文章
- Android 学习笔记之Volley(七)实现Json数据加载和解析...
学习内容: 1.使用Volley实现异步加载Json数据... Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- android学习笔记36——使用原始XML文件
XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- udacity android 学习笔记: lesson 4 part b
udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...
- Android学习笔记36:使用SQLite方式存储数据
在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...
- Android学习笔记之Activity详解
1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...
- Pro Android学习笔记 ActionBar(1):Home图标区
Pro Android学习笔记(四八):ActionBar(1):Home图标区 2013年03月10日 ⁄ 综合 ⁄ 共 3256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 ActionBar在A ...
- 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...
随机推荐
- pgm14
这部分讨论在有数据缺失情况下的 learning 问题,这里仍然假定了图结构是已知的. 首先需要讨论的是为什么会缺失,很多情况下缺失并不是“随机”的:有的缺失是人为的,那么某些情况下缺失的可以直接补上 ...
- LOJ114 k大(xiao)异或和(线性基)
构造线性基后将其消至对任意位至多只有一个元素该位为1.于是就可以贪心了,将k拆成二进制就好.注意check一下是否能异或出0. #include<iostream> #include< ...
- servlet表单中get和post方法的区别
Form中的get和post方法,在数据传输过程中分别对应了HTTP协议中的GET和POST方法.二者主要区别如下: 1.Get是用来从服务器上获得数据,而Post是用来向服务器上传递数据. 2.Ge ...
- MT【5】蝴蝶效应:一道递推式为二次的数列
评:蝴蝶效应[蝴蝶效应(The Butterfly Effect)是指在一个动力系统中,初始条件下微小的变化能带动整个系统的长期的巨 ...
- bat 脚本处理windows 文件
背景:以下脚本使用了导出文件列表.移动文件.复制文件.report 系统信息.分段执行的功能 主要针对在从事于Easeware公司中,对软件Bug中,所需文件的提取. 代码片段说明: cls ver ...
- 自学Zabbix13.1 分布式监控proxy介绍
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix13.1 分布式监控proxy介绍 zabbix2.4版本之前,zabbix提供了 ...
- 用ip代替机器名访问sharepoint 站点
1. aam 里加入一个ip的internet 2. iis里不用加上ip,但不要有host name 出现的问题: 1. 当打开站点里会出现这个错误 file not found 2. 当加授予 ...
- Azure HDInsight 上的 Spark 群集配合自定义的Python来分析网站日志
一.前言:本文是个实践博客,演示如何结合使用自定义库和 HDInsight 上的 Spark 来分析日志数据. 我们使用的自定义库是一个名为 iislogparser.py的 Python 库. 每步 ...
- [luogu1655][小朋友的球]
luogu1665 思路 一道第二类斯特兰数的模板题.只不过需要写个高精. f[i][j]表示前i个球放到j个盒子里的方案数.第i个球可以单独一个盒子,所以f[i][j]+=f[i-1][j-1].还 ...
- 初探angular2
Angular2 是一款开源JavaScript库,由Google维护,用来协助单一页面应用程序运行. Angular2 是 Angular 1.x 的升级版本,性能上得到显著的提高,能很好的支持 W ...