Android 蓝牙
添加权限:
<uses-permission Android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
- 客户端
开启蓝牙:
/**
* 打开蓝牙设备
*/
void openBT(){
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter!= null){
if (!mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.enable();
Log.d("qfopenBT","打开蓝牙成功");
}
}
}
搜索蓝牙:
/**
* 搜索蓝牙设备
* @param view
*/
@OnClick(R.id.btSearch)
public void startSearch(View view){
if(mBluetoothAdapter!= null &&mBluetoothAdapter.isEnabled()){
if (!mBluetoothAdapter.isDiscovering()){
mBluetoothAdapter.startDiscovery();
}
}
}
开启搜索是异步操作,发现设备后会发送广播,所以要定义广播接收者
在接收到广播后,获取广播里的蓝牙数据
private class BTBroadCastRevextends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent) {
String strAction = intent.getAction();
if (strAction.equals(BluetoothDevice.ACTION_FOUND)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mArrDevice.add(device);
mAdapter.notifyDataSetChanged();
}
else if(strAction.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
Log.d("qfonReceive","搜索完成");
}
}
}
//注册广播接收者
myReceive = newBTBroadCastRev();
IntentFilter ifFind = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(myReceive,ifFind);
IntentFilter ifFinishFind = newIntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(myReceive,ifFinishFind);
连接蓝牙,并开启发送数据线程:
/**
* 点击item,连接对应的蓝牙设备
*/
protected void connectBT() {
mLvDevice.setOnItemClickListener(newAdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent,View view, int position, longid) {
MyClientTask task = newMyClientTask();
task.execute(mArrDevice.get(position));
}
});
}
class MyClientTask extends AsyncTask<BluetoothDevice,Void,Void>{
@Override
protected VoiddoInBackground(BluetoothDevice... devices) {
BluetoothDevice device = devices[0];
try {
//使用安全连接,服务端也要一样使用安全连接,UUID也要跟服务器的监听UUID一致
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
socket.connect();
Log.d("qfdoInBackground_client","连接成功,开始发送数据");
byte[] btMsg =new String("Hello").getBytes();
socket.getOutputStream().write(btMsg,0,btMsg.length);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}
uuid可以通过uuidgen生成,生成结果类似以下结构:
5D3D5E52-338A-47B8-9F10-27ADF89E204E
- 服务端
开启蓝牙,跟客户端一样
启动服务线程
new RevTask().execute();
class RevTask extendsAsyncTask<Void,Void,String>{
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
tvMsg.setText(s);
}
@Override
protected StringdoInBackground(Void... params) {
try {
Log.d("qfdoInBackground","开始监听");
//要跟客户端uuid一致
BluetoothServerSocket sevSocket =mBluetoothAdapter.listenUsingRfcommWithServiceRecord("blue_service",MY_UUID_SECURE);
BluetoothSocket socket = sevSocket.accept();
if(socket != null){
Log.d("qfdoInBackground","连接成功");
InputStream stream = socket.getInputStream();
byte[] btRead =new byte[1024];
int iLength = stream.read(btRead);
Log.d("qfdoInBackground","读取数据成功"+iLength);
String strMsg =new String(btRead,"utf-8");
Log.d("qfdoInBackground",strMsg);
return strMsg;
}
else{
Log.d("qfdoInBackground","失败");
}
} catch (IOException e) {
e.printStackTrace();
Log.d("qfdoInBackground","异常");
}
return null;
}
}
上述代码没有实现配对,对应经典蓝牙通信,最好先进行配对再连接,已经配对的蓝牙设备可以直接通过adapter获取到
//得到所有已经配对的蓝牙适配器对象
Set<BluetoothDevice> devices = adapter.getBondedDevices();
没有配对的蓝牙设备,可以在扫描设备的广播通知中判断:
if
(device.getBondState() != BluetoothDevice.BOND_BONDED) { ...... }点击设备连接时,判断是否已经配对,如果已经配对,直接连接,如果没有配对,先配对:
- if (btDev.getBondState() == BluetoothDevice.BOND_NONE) {
- //利用反射方法调用BluetoothDevice.createBond(BluetoothDevice remoteDevice);
- Method createBondMethod = BluetoothDevice.class
- .getMethod("createBond");
- Log.d("BlueToothTestActivity", "开始配对");
- returnValue = (Boolean) createBondMethod.invoke(btDev);
- }else if(btDev.getBondState() == BluetoothDevice.BOND_BONDED){
- connect(btDev);
- }
配对结果也会通过广播传递结果信息:
- // 注册Receiver来获取蓝牙设备相关的结果
- IntentFilter intent = new IntentFilter();
- intent.addAction(BluetoothDevice.ACTION_FOUND);// 用BroadcastReceiver来取得搜索结果
- intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
- intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
- intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- registerReceiver(searchDevices, intent);
- if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){
- device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- switch (device.getBondState()) {
- case BluetoothDevice.BOND_BONDING:
- Log.d("BlueToothTestActivity", "正在配对......");
- break;
- case BluetoothDevice.BOND_BONDED:
- Log.d("BlueToothTestActivity", "完成配对");
- connect(device);//连接设备
- break;
- case BluetoothDevice.BOND_NONE:
- Log.d("BlueToothTestActivity", "取消配对");
- default:
- break;
- }
Android 蓝牙的更多相关文章
- android蓝牙打印机
您还未登录!|登录|注册|帮助 首页 业界 移动 云计算 研发 论坛 博客 下载 更多 reality_jie的专栏 编程的过程是一种微妙的享受 目录视图 摘要视图 订阅 CSDN2013 ...
- Android蓝牙实例(和单片机蓝牙模块通信)
最近做毕设,需要写一个简单的蓝牙APP进行交互,在网上也找了很多资料,终于给搞定了,这里分享一下^_^. 1.Android蓝牙编程 蓝牙3.0及以下版本编程需要使用UUID,UUID是通用唯一识别码 ...
- Android 蓝牙4.0 BLE
Android ble (Bluetooth Low Energy) 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用. BLE是蓝牙4.0的核心Profil ...
- android 蓝牙4.0 开发介绍
最近一直在研究一个蓝牙功能 由于本人是菜鸟 学起来比较忙 一直搞了好久才弄懂 , 网上对蓝牙4.0也就是几个个dome 抄来抄去,全是英文注解 , 对英语不好的朋友来说 真是硬伤 , 一些没必要的描 ...
- 【转】android蓝牙开发---与蓝牙模块进行通信--不错
原文网址:http://www.cnblogs.com/wenjiang/p/3200138.html 近半个月来一直在搞android蓝牙这方面,主要是项目需要与蓝牙模块进行通信.开头的进展很顺利, ...
- Android 蓝牙开发(整理大全)
Android蓝牙开发 鉴于国内Android蓝牙开发的例子很少,以及蓝牙开发也比较少用到,所以找的资料不是很全. (一): 由于Android蓝牙的通信都需要用到UUID,如果由手机发起搜索,当搜索 ...
- android -- 蓝牙 bluetooth (四)OPP文件传输
在前面android -- 蓝牙 bluetooth (一) 入门文章结尾中提到了会按四个方面来写这系列的文章,前面已写了蓝牙打开和蓝牙搜索,这次一起来看下蓝牙文件分享的流程,也就是蓝牙应用opp目录 ...
- android -- 蓝牙 bluetooth (三)搜索蓝牙
接上篇打开蓝牙继续,来一起看下蓝牙搜索的流程,触发蓝牙搜索的条件形式上有两种,一是在蓝牙设置界面开启蓝牙会直接开始搜索,另一个是先打开蓝牙开关在进入蓝牙设置界面也会触发搜索,也可能还有其它触发方式,但 ...
- android -- 蓝牙 bluetooth (一) 入门
前段时间在 网上看了一些关于android蓝牙的文章,发现大部分是基于老版本(4.1以前含4.1)的源码,虽然无碍了解蓝牙的基本原理和工作流程,但对着4.2.2的代码看起来总是有些遗憾.所以针对4.2 ...
- 深入了解Android蓝牙Bluetooth——《基础篇》
什么是蓝牙? 也可以说是蓝牙技术.所谓蓝牙(Bluetooth)技术,实际上是一种短距离无线电技术,是由爱立信公司公司发明的.利用"蓝牙"技术,能够有效地简化掌上电脑.笔记本电 ...
随机推荐
- java中分页效果的实现代码
首先是将分页所需的一些个资源 ,抽象出一个javabean对象-PageBean: 先把需要分页的数据或是记录都查询出来 存入一个集合类里如List或是Vector, 然后利用其sublist(int ...
- idea 光标变成粗体且当前文件搜索功能无法使用的问题
今天安装了idea最新版,安装完成后发现光标变成了粗体,并且快捷键在使用时出现了问题,比如:ctrl+F搜索功能无法使用 经过反复修改配置也无法改善情况,后来一次重启看到下面小窗弹出有关vim的一个提 ...
- JMeter学习-022-JMeter 分布式测试(性能测试大并发、远程启动解决方案)
在使用 JMeter 进行性能测试时,难免遇到要求并发请求数比较的场景,此时单台测试机的配置(CPU.内存.带宽等)可能无法支持此性能测试场景.因而,此时 JMeter 提供的分布式测试功能就有了用武 ...
- C# EasyUI树形结构权限管理模块
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 本节和大家探讨下C#使用EasyUI树形结构/Tree构 ...
- TP框架主要文件夹注释
TP框架主要文件夹注释 common -> 函数库目录 conf -> 配置文件目录lang -> 语言包librang -> 核心资源库 behacior -> 行为目 ...
- 添加右键菜单命令 在此处打开命令窗口(E)(带图标)
@color 0A @title 添加右键菜单命令 在此处打开命令窗口(^&E)(带图标) by wjshan0808 @echo off reg add HKCR\Directory\Bac ...
- poj 3254 Corn Fields
http://poj.org/problem?id=3254 Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissio ...
- HTML5探秘:用requestAnimationFrame优化Web动画
本文转载自: HTML5探秘:用requestAnimationFrame优化Web动画
- github创建文件夹
网页上只能通过在创建新文件的时候顺便创建文件夹(文件夹与文件用 / 隔开),例如home/test.md就在该仓库下创建了一个文件夹home,该文件夹下有一个新的文件test.md
- String 与StringBuilder有什么区别
C# String 对象是不可改变的.每次使用 System.String 类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的情况下,与 ...