概述

Android 传统蓝牙的使用,包括开关蓝牙、搜索设备、蓝牙连接、通信等。

详细

代码下载:http://www.demodashi.com/demo/10676.html

原文地址:

Android 蓝牙开发(一)蓝牙通信 CSDN

Android 蓝牙开发(一)蓝牙通信 简书

一、准备工作

开发环境:

jdk1.8

Eclipse Luna Service Release 1 (4.4.1)

运行环境:

华为荣耀6(Android4.4)、华为p9(Android7.0)

实现功能:

  • Android 蓝牙开发 (开关蓝牙、搜索设备、蓝牙配对、连接、通信、断开连接等)。

二、代码结构

代码包里面,有两个部分,一个是源码,一个是V7支持包。

三、程序实现-蓝牙通信

1 蓝牙基本操作

随着可穿戴设备的流行,研究蓝牙是必不可少的一门技术了。

总结了下蓝牙开发使用的一些东西分享一下。

蓝牙权限

首先需要AndroidManifest.xml文件中添加操作蓝牙的权限。

<uses-permissionandroid:name="Android.permission.BLUETOOTH" />
//允许程序连接到已配对的蓝牙设备。
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" />
//允许程序发现和配对蓝牙设备。

BluetoothAdapter

操作蓝牙主要用到的类 BluetoothAdapter类,使用时导包
import android.bluetooth.BluetoothAdapter;
源码具体位置frameworks/base/core/Java/android/bluetooth/BluetoothAdapter.java

BluetoothAdapter 代表本地设备的蓝牙适配器。该BluetoothAdapter可以执行基本的蓝牙任务,例如启
动设备发现,查询配对的设备列表,使用已知的MAC地址实例化一个BluetoothDevice类,并创建一个
BluetoothServerSocket监听来自其他设备的连接请求。

获取蓝牙适配器

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

开启蓝牙

if(!mBluetoothAdapter.isEnabled()){
//弹出对话框提示用户是后打开
Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabler, REQUEST_ENABLE);  //不做提示,直接打开,不建议用下面的方法,有的手机会有问题。  // mBluetoothAdapter.enable();
}

获取本地蓝牙信息

//获取本机蓝牙名称
String name = mBluetoothAdapter.getName();
//获取本机蓝牙地址
String address = mBluetoothAdapter.getAddress();
Log.d(TAG,"bluetooth name ="+name+" address ="+address);
//获取已配对蓝牙设备
Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
Log.d(TAG, "bonded device size ="+devices.size());
for(BluetoothDevice bonddevice:devices){  Log.d(TAG, "bonded device name ="+bonddevice.getName()+" address"+bonddevice.getAddress());
}

搜索设备

mBluetoothAdapter.startDiscovery();

停止搜索

mBluetoothAdapter.cancelDiscovery();

搜索蓝牙设备,该过程是异步的,通过下面注册广播接受者,可以监听是否搜到设备。

IntentFilter filter = new IntentFilter();
//发现设备
filter.addAction(BluetoothDevice.ACTION_FOUND);
//设备连接状态改变
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//蓝牙设备状态改变
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBluetoothReceiver, filter);

监听扫描结果

通过广播接收者查看扫描到的蓝牙设备,每扫描到一个设备,系统都会发送此广播(BluetoothDevice.ACTION_FOUNDE)。其中参数intent可以获取蓝牙设备BluetoothDevice。

该demo中是连接指定名称的蓝牙设备,BLUETOOTH_NAME为"Galaxy Nexus",如果扫描不到,记得改这个蓝牙名称。

private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver(){  @Override  public void onReceive(Context context, Intent intent) {  String action = intent.getAction();  Log.d(TAG,"mBluetoothReceiver action ="+action);  if(BluetoothDevice.ACTION_FOUND.equals(action)){//每扫描到一个设备,系统都会发送此广播。  //获取蓝牙设备  BluetoothDevice scanDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  if(scanDevice == null || scanDevice.getName() == null) return;  Log.d(TAG, "name="+scanDevice.getName()+"address="+scanDevice.getAddress());  //蓝牙设备名称  String name = scanDevice.getName();  if(name != null && name.equals(BLUETOOTH_NAME)){  mBluetoothAdapter.cancelDiscovery();  //取消扫描  mProgressDialog.setTitle(getResources().getString(R.string.progress_connecting));                   //连接到设备。  mBlthChatUtil.connect(scanDevice);  }  }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){  }}
};

设置蓝牙可见性

有时候扫描不到某设备,这是因为该设备对外不可见或者距离远,需要设备该蓝牙可见,这样该才能被搜索到。

可见时间默认值为120s,最多可设置300。

if (mBluetoothAdapter.isEnabled()) {  if (mBluetoothAdapter.getScanMode() !=   BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {  Intent discoverableIntent = new Intent(  BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);  discoverableIntent.putExtra(  BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);  startActivity(discoverableIntent);  }
}

2 服务端

android 蓝牙之间可以通过SDP协议建立连接进行通信,通信方式类似于平常使用socket。

首先创建BluetoothServerSocket ,BluetoothAdapter中提供了两种创建BluetoothServerSocket 方式,如下图所示为创建安全的RFCOMM Bluetooth socket,该连接是安全的需要进行配对。而通过listenUsingInsecureRfcommWithServiceRecord创建的RFCOMM Bluetooth socket是不安全的,连接时不需要进行配对。

其中的uuid需要服务器端和客户端进行统一。

private class AcceptThread extends Thread {  // 本地服务器套接字  private final BluetoothServerSocket mServerSocket;  public AcceptThread() {           BluetoothServerSocket tmp = null;  // 创建一个新的侦听服务器套接字  try {  tmp = mAdapter.listenUsingRfcommWithServiceRecord(  SERVICE_NAME, SERVICE_UUID);  //tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(SERVICE_NAME, SERVICE_UUID);  } catch (IOException e) {  Log.e(TAG, "listen() failed", e);  }  mServerSocket = tmp;  }  public void run() {  BluetoothSocket socket = null;  // 循环,直到连接成功  while (mState != STATE_CONNECTED) {  try {  // 这是一个阻塞调用 返回成功的连接  // mServerSocket.close()在另一个线程中调用,可以中止该阻塞  socket = mServerSocket.accept();  } catch (IOException e) {  Log.e(TAG, "accept() failed", e);  break;  }  // 如果连接被接受  if (socket != null) {  synchronized (BluetoothChatUtil.this) {  switch (mState) {  case STATE_LISTEN:  case STATE_CONNECTING:  // 正常情况。启动ConnectedThread。  connected(socket, socket.getRemoteDevice());  break;  case STATE_NONE:  case STATE_CONNECTED:  // 没有准备或已连接。新连接终止。  try {  socket.close();  } catch (IOException e) {  Log.e(TAG, "Could not close unwanted socket", e);  }  break;  }  }  }  }  if (D) Log.i(TAG, "END mAcceptThread");  }  public void cancel() {  if (D) Log.d(TAG, "cancel " + this);  try {  mServerSocket.close();  } catch (IOException e) {  Log.e(TAG, "close() of server failed", e);  }  }
}

mServerSocket通过accept()等待客户端的连接(阻塞),直到连接成功或失败。

3 客户端

客户端主要用来创建RFCOMM socket,并连接服务端。

先扫描周围的蓝牙设备,如果扫描到指定设备则进行连接。mBlthChatUtil.connect(scanDevice)连接到设备,

连接过程主要在ConnectThread线程中进行,先创建socket,方式有两种,

如下代码中是安全的(createRfcommSocketToServiceRecord)。另一种不安全连接对应的函数是createInsecureRfcommSocketToServiceRecord。

private class ConnectThread extends Thread {  private BluetoothSocket mmSocket;  private final BluetoothDevice mmDevice;  public ConnectThread(BluetoothDevice device) {  mmDevice = device;  BluetoothSocket tmp = null;  // 得到一个bluetoothsocket  try {  mmSocket = device.createRfcommSocketToServiceRecord  (SERVICE_UUID);  } catch (IOException e) {  Log.e(TAG, "create() failed", e);  mmSocket = null;  }  }  public void run() {  Log.i(TAG, "BEGIN mConnectThread");  try {   // socket 连接,该调用会阻塞,直到连接成功或失败  mmSocket.connect();  } catch (IOException e) {  connectionFailed();  try {//关闭这个socket  mmSocket.close();  } catch (IOException e2) {  e2.printStackTrace();  }  return;  }  // 启动连接线程  connected(mmSocket, mmDevice);  }  public void cancel() {  try {  mmSocket.close();  } catch (IOException e) {  Log.e(TAG, "close() of connect socket failed", e);  }  }
}

接着客户端socket主动连接服务端。连接过程中会自动进行配对,需要双方同意才可以连接成功。

4 数据传输

客户端与服务端连接成功后都会调用connected(mmSocket, mmDevice),创建一个ConnectedThread线程()。

该线程主要用来接收和发送数据。客户端和服务端处理方式一样。该线程通过socket获得输入输出流。

private InputStream mmInStream = socket.getInputStream();

private OutputStream mmOutStream =socket.getOutputStream();

发送数据

public void write(byte[] buffer) {  try {  mmOutStream.write(buffer);  // 分享发送的信息到Activity  mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer)  .sendToTarget();  } catch (IOException e) {  Log.e(TAG, "Exception during write", e);  }
}

接收数据

线程循环进行接收数据。

public void run() {  // 监听输入流  while (true) {  try {  byte[] buffer = new byte[1024];  // 读取输入流  int bytes = mmInStream.read(buffer);  // 发送获得的字节的ui activity  Message msg = mHandler.obtainMessage(MESSAGE_READ);  Bundle bundle = new Bundle();  bundle.putByteArray(READ_MSG, buffer);  msg.setData(bundle);  mHandler.sendMessage(msg);            } catch (IOException e) {  Log.e(TAG, "disconnected", e);  connectionLost();  break;  }  }
}

四、运行效果

1、运行,右键项目:Run as -》Android Application (备注:Eclipse需要配置Android开发环境)

2、运行效果如下:

客户端

服务端

注:本文著作权归作者,由demo大师(http://www.demodashi.com)宣传,拒绝转载,转载需要作者授权

Android -传统蓝牙通信聊天相关推荐

  1. Android开发——蓝牙通信实现

    Android开发--蓝牙通信实现 项目需求 项目主要代码及功能实现 AndroidManifest.xml res/values/string.xml activity_main.xml ChatS ...

  2. android 传统蓝牙

    前言 最近业务上需要用到蓝牙与硬件交互,经了解,现有分为传统蓝牙和低功耗蓝牙(BLE),本篇讲解传统蓝牙使用 现在市面上蓝牙模块大多数都支持低功耗蓝牙,传统蓝牙适用于较为耗电的操作,如 Android ...

  3. java实现蓝牙通信程序_Android蓝牙通信聊天实现发送和接受功能

    很不错的蓝牙通信demo实现发送和接受功能,就用了两个类就实现了,具体内容如下 说下思路把 主要有两个类主界面类和 蓝牙聊天服务类. 首先创建线程 实际上就是创建BluetoothChatServic ...

  4. Android Studio 蓝牙通信BlueTooth

    BlueTooth蓝牙通信 作业内容 配置蓝牙使用权限 页面布局 Layout文件夹中 Values文件夹中 Menu文件夹中 事件监听控制 服务组件ChatService.java weixinFr ...

  5. android 传统蓝牙Bluetooth联通性

    Android平台包含了对蓝牙网络协议栈的支持,它允许一个蓝牙设备跟其他的蓝牙设备进行无线的数据交换.应用程序通过Android蓝牙API提供访问蓝牙的功能.这些API会把应用程序无线连接到其他的蓝牙 ...

  6. android studio——蓝牙通信

    文章目录 一.结果展示 二.核心代码 1.AndroidManifest.xml文件 2.MainActivity.java文件 3.activity.xml文件 一.结果展示 点击"打开手 ...

  7. Android 传统蓝牙配对连接断开 附demo

    简单的描述下分享给大家个demo: 网上找了一大堆,刚开始配对是没问题的,但是断开连接和连接设备就出现很多报错,用的是 BluetoothSocket.connect,发现完全不是同一个方向,一直报错 ...

  8. 蓝牙聊天App设计3:Android Studio制作蓝牙聊天通讯软件(完结,蓝牙连接聊天,结合生活情景进行蓝牙通信的通俗讲解,以及代码功能实现,内容详细,讲解通俗易懂)

    前言:蓝牙聊天App设计全部有三篇文章(一.UI界面设计,二.蓝牙搜索配对连接实现,三.蓝牙连接聊天),这篇文章是:三.蓝牙连接聊天. 课程1:Android Studio小白安装教程,以及第一个An ...

  9. Android BLE设备蓝牙通信框架BluetoothKit

    BluetoothKit是一款功能强大的Android蓝牙通信框架,支持低功耗蓝牙设备的连接通信.蓝牙广播扫描及Beacon解析. 关于该项目的详细文档请关注:https://github.com/d ...

最新文章

  1. 文件系统_文件系统基础总结
  2. NYOJ 975 关于521
  3. python列表框_「每日一练」Python列表框部件的运用
  4. 结对开发——求最大值
  5. WAMP Server 无法启动的解决方法
  6. oracle两个约束,Oracle中的约束介绍(2)
  7. java 指针 引用_java中的引用与c中的指针
  8. Nginx之location配置
  9. Python装饰器几个有用又好玩的例子
  10. 皮克定理 poj2954
  11. 常见笔顺错误的字_有哪些常见笔顺错误?
  12. Android 高通8909 系统之路之 裁剪系统 一
  13. SSM遇到的表单问题:The server cannot or will not process the request due to something that is perceived to b
  14. 2018年Sketch UI界面设计套件前十了解下!
  15. C语言中excit函数,2010年12月英语四级全真预测试卷及答案解析(4)
  16. 风声,雨声,读书声-------候捷和孟岩的谈话
  17. 2020年前端安全综述-填坑记
  18. 【U3D日记-2016年10月28日】float转int 误差!
  19. 服务级别协议(SLA)与运行水平协议(OLA)
  20. 高德地图使用-高亮某块区域

热门文章

  1. 12006.eeprom之M24C02
  2. JLink v8固件丢失修复教程
  3. 【日志】数字电路电子钟制作日志
  4. 由PPPOE看Linux网络协议栈的实现
  5. 查询oracle 表达小,oracle中sql语句小练习(使用连接查询)
  6. linux下赛车游戏,SuperTuxKart 1.0 发布,开源Linux赛车游戏
  7. 知易游戏开发教程cocos2d-x移植版001
  8. .net加载失败的程序集重新加载
  9. 17.3.10--C语言运行的步骤
  10. hdu 1760 DFS+博弈