Android适配安卓6.0蓝牙通讯实现过程

事先说明:
安卓蓝牙需要定位权限申请,在安卓6.0需要用户手动确认权限后才能使用,各位可以自行查询资料实现,如果嫌麻烦,可以用第三方Bmob集成好的工具类进行实现,详细可以看http://blog.csdn.net/qq_30379689/article/details/52223244

蓝牙连接过程:
1、查询用户是否开启蓝牙。
2、搜索附近的可用的蓝牙。
3、进行蓝牙配对。
4、进行蓝牙连接。
5、获取输入流和输出流。
6、发送消息。

晒上我自己画的美图:

实验效果图:

实现需要的权限:由于安卓4.x以上的版本使用蓝牙,需要开启定位权限才能搜索到附近的蓝牙设备

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

服务端

实现思路:
1、拿到本地蓝牙设备。
2、蓝牙之间的通讯需要一个唯一识别UUID来匹配正确的设备,使用UUID获取蓝牙的通讯Socket。
3、开启获取数据的线程

public class MainActivity extends AppCompatActivity implements View.OnClickListener { 

 BluetoothSocket BTSocket;
 BluetoothAdapter BTAdapter;
 Button bt_start;
 TextView tv_msg;
 StringBuilder sb; 

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 bt_start = (Button) findViewById(R.id.bt_start);
 tv_msg = (TextView) findViewById(R.id.tv_msg);
 bt_start.setOnClickListener(this);
 sb = new StringBuilder();
 //拿到本地蓝牙设备
 BTAdapter = BluetoothAdapter.getDefaultAdapter();
 } 

 /**
 * UI文本输出
 *
 * @param msg
 */
 public void show(String msg) {
 sb.append(msg + "\n");
 runOnUiThread(new Runnable() {
 @Override
 public void run() {
 tv_msg.setText(sb.toString());
 }
 });
 } 

 @Override
 public void onClick(View v) {
 //开启服务器
 ServerThread startServerThread = new ServerThread();
 startServerThread.start();
 } 

 /**
 * 开启服务器
 */
 private class ServerThread extends Thread {
 public void run() {
 try {
 BluetoothServerSocket mserverSocket = BTAdapter.listenUsingRfcommWithServiceRecord("btspp",
  UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
 show("服务端:等待连接"); 

 BTSocket = mserverSocket.accept();
 show("服务端:连接成功"); 

 readThread mreadThread = new readThread();
 mreadThread.start();
 show("服务端:启动接受数据");
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 } 

 /**
 * 读取数据
 */
 private class readThread extends Thread {
 public void run() {
 byte[] buffer = new byte[1024];
 int bytes;
 InputStream mmInStream = null;
 try {
 mmInStream = BTSocket.getInputStream();
 show("服务端:获得输入流");
 } catch (IOException e1) {
 e1.printStackTrace();
 }
 while (true) {
 try {
  if ((bytes = mmInStream.read(buffer)) > 0) {
  byte[] buf_data = new byte[bytes];
  for (int i = 0; i < bytes; i++) {
  buf_data[i] = buffer[i];
  }
  String s = new String(buf_data);
  show("服务端:读取数据了~~" + s);
  }
 } catch (IOException e) {
  try {
  mmInStream.close();
  } catch (IOException e1) {
  e1.printStackTrace();
  }
  break;
 }
 }
 }
 } 

}

客户端

实现思路:
1、检查是否开启蓝牙。
2、注册一系列蓝牙的广播。
3、由于蓝牙每经过一个阶段都会发送一个广播,根据广播来实现对应的方法。
4、蓝牙配对->蓝牙连接->发送消息(UUID必须相同)

public class MainActivity extends AppCompatActivity implements View.OnClickListener { 

 private TextView tv_msg;
 private Button bt_search, bt_send;
 private BluetoothSocket BTSocket;
 private BluetoothAdapter BTAdapter;
 private BluetoothDevice device;
 private StringBuilder sb; 

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main); 

 bt_search = (Button) findViewById(R.id.bt_search);
 bt_send = (Button) findViewById(R.id.bt_send);
 tv_msg = (TextView) findViewById(R.id.tv_msg);
 bt_search.setOnClickListener(this);
 bt_send.setOnClickListener(this);
 sb = new StringBuilder(); 

 show("客户端:检查BT");
 checkBT(this);
 show("客户端:注册接收者");
 registerBTReceiver();
 } 

 /**
 * UI文本输出
 *
 * @param msg
 */
 public void show(String msg) {
 sb.append(msg + "\n");
 runOnUiThread(new Runnable() {
 @Override
 public void run() {
 tv_msg.setText(sb.toString());
 }
 });
 } 

 @Override
 public void onClick(View v) {
 switch (v.getId()) {
 case R.id.bt_search:
 show("客户端:开始寻找设备");
 BTAdapter.startDiscovery();
 break;
 case R.id.bt_send:
 sendMessage();
 break;
 }
 } 

 /**
 * 检查蓝牙
 */
 public void checkBT(Context context) {
 BTAdapter = BluetoothAdapter.getDefaultAdapter();
 if (BTAdapter != null) {
 if (!BTAdapter.isEnabled()) {
 Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
 // 设置蓝牙可见性,最多300秒
 intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
 context.startActivity(intent);
 }
 } else {
 System.out.println("本地设备驱动异常!");
 }
 } 

 /**
 * 开启客户端
 */
 private class clientThread extends Thread {
 public void run() {
 try {
 //创建一个Socket连接:只需要服务器在注册时的UUID号
 BTSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
 //连接
 show("客户端:开始连接...");
 BTSocket.connect();
 show("客户端:连接成功");
 //启动接受数据
 show("客户端:启动接受数据");
 readThread mreadThread = new readThread();
 mreadThread.start();
 } catch (IOException e) {
 show("客户端:连接服务端异常!断开连接重新试一试");
 e.printStackTrace();
 }
 }
 } 

 /**
 * 读取数据
 */
 private class readThread extends Thread {
 public void run() {
 byte[] buffer = new byte[1024];
 int bytes;
 InputStream is = null;
 try {
 is = BTSocket.getInputStream();
 show("客户端:获得输入流");
 } catch (IOException e1) {
 e1.printStackTrace();
 }
 while (true) {
 try {
  if ((bytes = is.read(buffer)) > 0) {
  byte[] buf_data = new byte[bytes];
  for (int i = 0; i < bytes; i++) {
  buf_data[i] = buffer[i];
  }
  String s = new String(buf_data);
  show("客户端:读取数据了" + s);
  }
 } catch (IOException e) {
  try {
  is.close();
  } catch (IOException e1) {
  e1.printStackTrace();
  }
  break;
 }
 }
 }
 } 

 /**
 * 发送数据
 */
 public void sendMessage() {
 if (BTSocket == null) {
 Toast.makeText(this, "没有连接", Toast.LENGTH_SHORT).show();
 return;
 }
 try {
 OutputStream os = BTSocket.getOutputStream();
 os.write("我爱你dahsid132456@#%¥*".getBytes());
 os.flush();
 show("客户端:发送信息成功");
 } catch (IOException e) {
 e.printStackTrace();
 }
 } 

 /**
 * 注册广播
 */
 public void registerBTReceiver() {
 // 设置广播信息过滤
 IntentFilter intentFilter = new IntentFilter();
 intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
 intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
 intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
 intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
 intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
 // 注册广播接收器,接收并处理搜索结果
 registerReceiver(BTReceive, intentFilter);
 } 

 /**
 * 注销广播
 */
 public void unregisterBTReceiver() {
 unregisterReceiver(BTReceive);
 } 

 @Override
 protected void onDestroy() {
 super.onDestroy();
 unregisterBTReceiver();
 } 

 /**
 * 广播接收者
 */
 private BroadcastReceiver BTReceive = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
 String action = intent.getAction();
 if (BluetoothDevice.ACTION_FOUND.equals(action)) {
 device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
 show("客户端:找到的BT名:" + device.getName());
 // 如果查找到的设备符合要连接的设备,处理
 if (device.getName().equalsIgnoreCase("xu")) {
  show("客户端:配对xu蓝牙:");
  // 搜索蓝牙设备的过程占用资源比较多,一旦找到需要连接的设备后需要及时关闭搜索
  BTAdapter.cancelDiscovery();
  // 获取蓝牙设备的连接状态
  int connectState = device.getBondState();
  switch (connectState) {
  // 未配对
  case BluetoothDevice.BOND_NONE:
  show("客户端:开始配对:");
  try {
  Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
  createBondMethod.invoke(device);
  } catch (Exception e) {
  e.printStackTrace();
  }
  break;
  // 已配对
  case BluetoothDevice.BOND_BONDED:
  try {
  show("客户端:开始连接:");
  clientThread clientConnectThread = new clientThread();
  clientConnectThread.start();
  } catch (Exception e) {
  e.printStackTrace();
  }
  break;
  }
 }
 } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
 // 获取蓝牙设备的连接状态
 int connectState = device.getBondState();
 // 已配对
 if (connectState == BluetoothDevice.BOND_BONDED) {
  try {
  show("客户端:开始连接:");
  clientThread clientConnectThread = new clientThread();
  clientConnectThread.start();
  } catch (Exception e) {
  e.printStackTrace();
  }
 }
 }
 show(action);
 }
 };
}

蓝牙广播内容:

ACTION_STATE_CHANGED   当你蓝牙开启或者关闭的时候发送
ACTION_FOUND  当你匹配到附近蓝牙设备时发送
ACTION_DISCOVERY_STARTED  当你开始搜索附近蓝牙设备时发送
ACTION_DISCOVERY_FINISHED  当你结束搜索附近蓝牙设备时发送
ACTION_BOND_STATE_CHANGED  当你蓝牙设备匹配状态发生变化时发送

源码下载:http://xiazai.jb51.net/201609/yuanma/Androidrobot(jb51.net).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android控制闪光灯的方法(打开与关闭)

    本文实例讲述了Android控制闪光灯的方法.分享给大家供大家参考,具体如下: 最近想做一个手电筒,在网上搜到一点资料 首先闪光灯可以用android.hardware.camera来控制 1. 在Manifest.xml文件中添加权限 复制代码 代码如下: <uses-permission android:name="android.permission.CAMERA" /> 2. 打开闪光灯 try{ m_Camera = Camera.open(); Camera.P

  • 控制Android LED灯颜色的代码实例

    很多Android手机上都配有LED灯,比如HTC的手机在充电.新来短信等时候都会有响应的指示,其实很简单的这都是NotificationManager的一些参数而已,下面Android123给大家说下如何通过代码控制LED灯的闪烁,因为有些机型没有LED灯或颜色种类较少,发布时需要真机观察. 复制代码 代码如下: final int ID_LED=19871103;         NotificationManager nm=(NotificationManager)getSystemSer

  • Android软键盘弹出时的界面控制方法

    本文实例讲述了Android软键盘弹出时的界面控制方法.分享给大家供大家参考,具体如下: 有时候androidactivity弹出软键盘后布局改变 下面有三种模式可以改变软键盘弹出以后的显示形式 模式一:压缩模式软键盘弹出以后,会压缩原先的大小 我们可以在AndroidManifet.xml中对Activity进行设置.如: android:windowSoftInputMode="stateUnchanged|adjustResize" 模式二:平移模式 软键盘弹出以后,不会压缩原先

  • Android编程调用红外线遥控功能示例

    本文实例讲述了Android编程调用红外线遥控功能.分享给大家供大家参考,具体如下: Android API Demos中有红外线遥控的小例子,在网上找了很久相关的资料,发现比较少,或许找的方法不对. Github上有一个与之相关的开源项目https://github.com/timnew/AndroidInfrared,还没来得及学习.希望有相关资料或学习项目的大神们多指导 . /** * Android红外线遥控官方Demo * * @description: * @author ldm *

  • Android蓝牙开发深入解析

    1. 使用蓝牙的响应权限 复制代码 代码如下: <uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 2. 配置本机蓝牙模块 在这里首先要了解对蓝牙操作一个核心类BluetoothAdapter 复制代码 代码如下: Bluetoot

  • Android基础之使用Fragment控制切换多个页面

    今天讲解一下Fragment的控制,主要是切换View和页面替换等操作.还有就是如何获取Fragment的管理对象,以及与Activity的通信方式.1.管理Fragment要在activity中管理fragment,需要使用FragmentManager. 通过调用activity的getFragmentManager()取得它的实例. •可以通过FragmentManager做一些事情, 包括: 使用findFragmentById()(用于在activity layout中提供一个UI的f

  • Android应用中实现手势控制图片缩放的完全攻略

    一.概述 现在app中,图片预览功能肯定是少不了的,用户基本已经形成条件反射,看到小图,点击看大图,看到大图两个手指开始进行放大,放大后,开始移动到指定部位~~~ 我相信看图的整个步骤,大家或者说用户应该不希望被打断把~~~"我擦,竟然不能放大,什么玩意,卸了~~" , "我擦,竟然不能移动,留有何用,卸了~~". 哈~所以对于图片的预览,一来,我们要让用户爽:二来,我们作为开发者,也得知道如何实现~~~ 想要做到图片支持多点触控,自由的进行缩放.平移,需要了解几个

  • Android蓝牙通信聊天实现发送和接受功能

    很不错的蓝牙通信demo实现发送和接受功能,就用了两个类就实现了,具体内容如下 说下思路把 主要有两个类 主界面类 和 蓝牙聊天服务类 . 首先创建线程 实际上就是创建BluetoothChatService() (蓝牙聊天服务类) 这个时候把handler 传过去 这样就可以操作UI 界面了,在线程中不断轮询读取蓝牙消息,当主界面点击发送按钮时 调用BluetoothChatService 的发送方法write 方法,这里的write 方法 使用了handler 发送消息,在主界面显示,另一个

  • Android提高之蓝牙传感应用实例

    前面文章介绍了Android利用麦克风采集并显示模拟信号的实现方法,这种采集手段适用于无IO控制.单纯读取信号的情况.如果传感器本身需要包含控制电路(例如采集血氧信号需要红外和红外线交替发射),那么传感器本身就需要带一片主控IC,片内采集并输出数字信号了.Android手机如何在不改硬件电路的前提下与这类数字传感器交互呢?可选的通信方式就有USB和蓝牙,两种方式各有好处:USB方式可以给传感器供电,蓝牙方式要自备电源:USB接口标准不一,蓝牙普遍支持SPP协议.本文就选择蓝牙方式做介绍,介绍An

  • android 动态控制状态栏显示和隐藏的方法实例

    方法一:(经试验无效,但网上广为流传,也许是我使用方法不当,有待进一步验证--) android想要应用运行时全屏有一种方法是在activity的onCreat方法中加入如下代码:getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                 WindowManager.LayoutParams.FLAG_FULLSCREEN);并且需要在setContentView()之前,否则无效过.从这么多的

  • Android系统中的蓝牙连接程序编写实例教程

    Bluetooth结构 1.JAVA层 frameworks/base/core/java/android/bluetooth/ 包含了bluetooth的JAVA类. 2.JNI层 frameworks/base/core/jni/android_bluetooth_开头的文件 定义了bluez通过JNI到上层的接口. frameworks/base/core/jni/android_server_bluetoothservice.cpp 调用硬件适配层的接口system/bluetooth/

随机推荐