Android——蓝牙通信
来源:互联网 发布:greenvpn软件下载 编辑:程序博客网 时间:2024/04/30 23:47
最近想做一个项目,Android手表将采集到的数据实时的发送到手机上,选择的数据传递方式为蓝牙通信。由于暂时没有手表,所以在两台手机上进行实验。(最终的结果发现通信成功好像跟手机系统有关,后面会具体说道这个问题)
下面开始介绍系统蓝牙服务的使用,最要涉及到使用四个类:
BluetoothAdapter,BluetoothDevice,BluetoothServerSocket,BluetoothSocket.
发现了没,后面的两个类和java的ServerSocket.Socket很类似(不存在继承关系)。他们的用法大致都差不多,只不过创建的方式不一样(仅此而已)。所以在后面会发现一旦获得了BluetoothServerScoket和BluetoothSocket,就和普通的Sokcet编程一样
1.蓝牙的开启
//获得系统蓝牙服务BluetoothAdapter adapter=BluetoothAdpater.getDefaultAdapter();//判断蓝牙是否开启if(!adapter.isEnabled()) adapter.enable();//开启蓝牙//判断蓝牙是否设置为可被其他蓝牙设备发现if(!adapter.isDiscovering()){ Intent i=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//设置可被发现的时间 i.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,120000);}startActivity(i);//会弹出一个对话框,询问是否允许被发现adapter.startDiscovery();//开启被发现
2.查找设备
在上面的步骤执行完,开启了蓝牙之后,需要手机查找周围的蓝牙设备
//通过注册广播的方式,将查找的结果返回给当前的Activity,所以先需要定义一个BroadcastReceiver对象,也可以定义一个内部类继承自BroadcastReceiver(个人喜欢直接写匿名内部类)
private BroadcastReceiver receiver=new BroadcastReceiverprivate BroadcastReceiver receiver = new BroadcastReceiver(){ @Override public void onReceiver(Contect context,Intent intent){ //判断当前的动作是什么类型 if(intent.getAction()==BluetoothDevice.ACTION_FOUND); //BluetoothDevices实现了可序列化接口,可以直接放在Intent中传递 BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //对于得到的deceive,可以获得它的名字等属性,将他们加入到List中显示,以及将deceive用List保存起来 }};//定义了BroadcastReceiver对象receiver,就可以来使用它来监听蓝牙查找情况IntentFilter intentFilter=new IntentFilter(BluetoothDevice.ACTION_FOUND);registerReceiver(receiver,intentFilter);//注册广播
3.创建BluetoothSocket
在上面通过注册广播的方式,我们可以得到周围的deceive信息。
通过的deceive来创建BluetoothSocket
有两种方式
- 通过直接调用:
//UUID="00001101-0000-1000-8000-00805F9B34FB" BluetoothSocket socket=deceive.createRfcommSocketToServiceRecord(UUID.fromString(Config.UUID));
- 利用反射的方式
Method method=device.getClass().getMethod("createRfcommSocket",new Class[]{int.class});socket=method.invoke(device,1);
4.获得BluetoothServerSocket
和获得BluetoothSocket一样两种方式
- 通过直接调用:
//UUID="00001101-0000-1000-8000-00805F9B34FB" BluetoothServerSocket serverSocket=bluetoothAdapter.listenUsingRfcommWithServiceRecord(UUID.fromString(Config.UUID));
- 利用反射的方式
Method method=bluetoothAdapter.getClass().getMethod("listenUsingRfcommOn",new Class[]{int.class});serverSocket=method.invoke(bluetoothAdapter,1);
进行客户端服务端通信
- 服务端需要向获得一个BluetoothServerSocket,上面已经介绍了怎么获取
按照Socket编程的一般方式进行处理即可
//开启一个线程,监听是否有客户端连接(我是将通信放在一个单独的类里,这个类继承自Thread类),run方法里处理,在初始化的时候已经得到bluetoothAdapter,bluetoothServerSocket和一个主线程传递过来的handlepublic void run(){ // boolean getSocket=false;全局变量 //获得服务端的socket while(!getSocket){ socket=bluetoothServerSocket.accept();//是不是和将java Socket编程一样 if(socket!=null) getSocket=true; } //开始读取数据 startReading();}//简单的写写读取过程,异常处理不写了private void startReading(){ while(isReading){//isReading全局变量 if(socket==null) break; InputStream in=socket.getInputStremam(); byte[] bytes=new byte[in.available()]; if(in.read(bytes,0,in.available())>0){ //通过handle将读取到的数据发出去 Message msg=new Message(); msg.what=1;//1表示读取成功 msg.obj=new String(bytes); handle.sendMessage(msg); } //注意read操作会阻塞子线程,所以最好sleep sleep(100);//抛出异常 }}//写操作一样pulic void write(String str){ if(socket!=null){ OutputStream out=socket.getOutputStream(); byte[] bytes=str.getBytes(); out.write(bytes,0,bytes.length); out.flush(); //注意不要关闭读写,可能导致socket连接中断 }}
客户端通信
@Overridepublic void run() { try { socket =device.createRfcommSocketToServiceRecord(UUID.fromString(Config.UUID)); socket.connect(); } catch (IOException e) { e.printStackTrace(); Log.e("TAG", "socket 创建失败" + e.toString()); handler.sendEmptyMessage(Config.STATUES_CONNECT_FAILED); } if (socket.isConnected()) handler.sendEmptyMessage(Config.STATUES_CONNECT_SUCCESS); else handler.sendEmptyMessage(Config.STATUES_CONNECT_FAILED); while (isReading) { try { sleep(100); if (socket == null) continue; if (in == null) in = socket.getInputStream(); byte[] bytes = new byte[in.available()]; if (in.read(bytes,0,in.available()) > 0) { Message msg = new Message(); msg.what = Config.STATUES_READ_SUCCESS; msg.obj = new String(bytes); handler.sendMessage(msg); } } catch (IOException e) { e.printStackTrace(); handler.sendEmptyMessage(Config.STATUES_READ_FAILED); } catch (InterruptedException e) { e.printStackTrace(); } } }
存在的问题
- 用BufferReader包装socket的输入流读取数据出错
- 用发射的方法获取BluetoothServerSocket和BluetoothSocket出问题
- 两台手机,一台华为的P6一台魅蓝note2,华为手机当服务端魅蓝当客户端没问题,但魅蓝但服务端就报错,说没有APN 系统权限之类的
0 0
- Android——蓝牙通信
- Android 蓝牙通信——AndroidBluetoothManager
- Android——蓝牙Socket通信
- Android蓝牙通信——与蓝牙模块进行通信传输数据
- Android 蓝牙开发-蓝牙通信
- Android 蓝牙通信开发(三)蓝牙通信
- Android蓝牙通信——安卓蓝牙obtainMessage数据传输部分数据丢失乱序问题
- Android 蓝牙五子棋[可人机对战] —— 蓝牙通信篇
- Android开发之蓝牙(一)——基于SPP协议蓝牙模块通信
- Android开发之蓝牙(二)——基于BLE协议蓝牙模块通信
- Android蓝牙通信
- Android蓝牙通信
- android 蓝牙通信编程
- Android蓝牙通信
- Android 通信--蓝牙
- Android 通信--蓝牙
- Android蓝牙通信
- Android-蓝牙通信
- 14.15 InnoDB Backup and Recovery Innodb备份和恢复
- Oolong and Gnoloo
- 1054. The Dominant Color (20)【水题】——PAT (Advanced Level) Practise
- 嵌入式C的十六个问题的中英文版
- The application could not be verified.
- Android——蓝牙通信
- java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission:
- 前端开发常用的工具与网站备忘
- centos 7 全新版本和全新命令用到崩溃
- Java中 <? super T>,<? extends T>,和<T>的区别
- 12.7 数据仓库课
- Android通过剪切板传递数据
- 中国计算机学会推荐国际学术刊物 (人工智能与模式识别)
- jQuery 流星雨特效