package com.example.android.BluetoothChat;

/**

* 描述:蓝牙服务核心类

*/

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.UUID;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice;

import android.bluetooth.BluetoothServerSocket;

import android.bluetooth.BluetoothSocket;

import android.content.Context;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

public class BluetoothChatService {

// 测试数据

private static final String TAG = "BluetoothChatService";

private static final boolean D = true;

private static final String NAME = "BluetoothChat";

// 声明一个唯一的UUID

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");        //change by chongqing jinou

private final BluetoothAdapter mAdapter;

private final Handler mHandler;

private AcceptThread mAcceptThread;

private ConnectThread mConnectThread;

private ConnectedThread mConnectedThread;

private int mState;

// 常量,显示当前的连接状态

public static final int STATE_NONE = 0;

public static final int STATE_LISTEN = 1;

public static final int STATE_CONNECTING = 2;

public static final int STATE_CONNECTED = 3;

public BluetoothChatService(Context context, Handler handler) {

mAdapter = BluetoothAdapter.getDefaultAdapter();

mState = STATE_NONE;

mHandler = handler;

}

/**

* 设置当前的连接状态

* @param state  连接状态

*/

private synchronized void setState(int state) {

if (D) Log.d(TAG, "setState() " + mState + " -> " + state);

mState = state;

// 通知Activity更新UI

mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();

}

/**

* 返回当前连接状态

*

*/

public synchronized int getState() {

return mState;

}

/**

*开始聊天服务

*

*/

public synchronized void start() {

if (D) Log.d(TAG, "start");

if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}

if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

if (mAcceptThread == null) {

mAcceptThread = new AcceptThread();

mAcceptThread.start();

}

setState(STATE_LISTEN);

}

/**

* 连接远程设备

* @param device  连接

*/

public synchronized void connect(BluetoothDevice device) {

if (D) Log.d(TAG, "连接到: " + device);

if (mState == STATE_CONNECTING) {

if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}

}

if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

mConnectThread = new ConnectThread(device);

mConnectThread.start();

setState(STATE_CONNECTING);

}

/**

* 启动ConnectedThread开始管理一个蓝牙连接

*/

public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {

if (D) Log.d(TAG, "连接");

if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}

if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}

mConnectedThread = new ConnectedThread(socket);

mConnectedThread.start();

Message msg = mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_DEVICE_NAME);

Bundle bundle = new Bundle();

bundle.putString(BluetoothChatActivity.DEVICE_NAME, device.getName());

msg.setData(bundle);

mHandler.sendMessage(msg);

setState(STATE_CONNECTED);

}

/**

* 停止所有线程

*/

public synchronized void stop() {

if (D) Log.d(TAG, "stop");

setState(STATE_NONE);

if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}

if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}

}

/**

* 以非同步方式写入ConnectedThread

* @param out

*/

public void write(byte[] out) {

ConnectedThread r;

synchronized (this) {

if (mState != STATE_CONNECTED) return;

r = mConnectedThread;

}

r.write(out);

}

/**

* 无法连接,通知Activity

*/

private void connectionFailed() {

setState(STATE_LISTEN);

Message msg = mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_TOAST);

Bundle bundle = new Bundle();

bundle.putString(BluetoothChatActivity.TOAST, "无法连接设备");

msg.setData(bundle);

mHandler.sendMessage(msg);

}

/**

* 设备断开连接,通知Activity

*/

private void connectionLost() {

Message msg = mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_TOAST);

Bundle bundle = new Bundle();

bundle.putString(BluetoothChatActivity.TOAST, "设备断开连接");

msg.setData(bundle);

mHandler.sendMessage(msg);

}

/**

* 监听传入的连接

*/

private class AcceptThread extends Thread {

private final BluetoothServerSocket mmServerSocket;

public AcceptThread() {

BluetoothServerSocket tmp = null;

try {

tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);

} catch (IOException e) {

Log.e(TAG, "listen() failed", e);

}

mmServerSocket = tmp;

}

public void run() {

if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);

setName("AcceptThread");

BluetoothSocket socket = null;

while (mState != STATE_CONNECTED) {

try {

socket = mmServerSocket.accept();

} catch (IOException e) {

Log.e(TAG, "accept() 失败", e);

break;

}

// 如果连接被接受

if (socket != null) {

synchronized (BluetoothChatService.this) {

switch (mState) {

case STATE_LISTEN:

case STATE_CONNECTING:

// 开始连接线程

connected(socket, socket.getRemoteDevice());

break;

case STATE_NONE:

case STATE_CONNECTED:

// 没有准备好或已经连接

try {

socket.close();

} catch (IOException e) {

Log.e(TAG, "不能关闭这些连接", e);

}

break;

}

}

}

}

if (D) Log.i(TAG, "结束mAcceptThread");

}

public void cancel() {

if (D) Log.d(TAG, "取消 " + this);

try {

mmServerSocket.close();

} catch (IOException e) {

Log.e(TAG, "关闭失败", e);

}

}

}

private class ConnectThread extends Thread {

private final BluetoothSocket mmSocket;

private final BluetoothDevice mmDevice;

public ConnectThread(BluetoothDevice device) {

mmDevice = device;

BluetoothSocket tmp = null;

try {

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

} catch (IOException e) {

Log.e(TAG, "create() 失败", e);

}

mmSocket = tmp;

}

public void run() {

Log.i(TAG, "开始mConnectThread");

setName("ConnectThread");

mAdapter.cancelDiscovery();

try {

mmSocket.connect();

} catch (IOException e) {

connectionFailed();

try {

mmSocket.close();

} catch (IOException e2) {

Log.e(TAG, "关闭连接失败", e2);

}

BluetoothChatService.this.start();

return;

}

synchronized (BluetoothChatService.this) {

mConnectThread = null;

}

connected(mmSocket, mmDevice);

}

public void cancel() {

try {

mmSocket.close();

} catch (IOException e) {

Log.e(TAG, "关闭连接失败", e);

}

}

}

/**

* 处理所有传入和传出的传输

*/

private class ConnectedThread extends Thread {

private final BluetoothSocket mmSocket;

private final InputStream mmInStream;

private final OutputStream mmOutStream;

public ConnectedThread(BluetoothSocket socket) {

Log.d(TAG, "创建 ConnectedThread");

mmSocket = socket;

InputStream tmpIn = null;

OutputStream tmpOut = null;

// 得到BluetoothSocket输入和输出流

try {

tmpIn = socket.getInputStream();

tmpOut = socket.getOutputStream();

} catch (IOException e) {

Log.e(TAG, "temp sockets not created", e);

}

mmInStream = tmpIn;

mmOutStream = tmpOut;

}

public void run() {

Log.i(TAG, "BEGIN mConnectedThread");

int bytes;

String str1 = "";

// 循环监听消息

while (true) {

try {

byte[] buffer = new byte[256];

bytes = mmInStream.read(buffer);

String readStr = new String(buffer, 0, bytes);

String str = bytes2HexString(buffer).replaceAll("00","").trim();

if(bytes>0)

{

if (str.endsWith("0D")) {

byte[] buffer1 = (str1+readStr).getBytes();

mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_READ, buffer1.length, -1, buffer1)

.sendToTarget();

str1 = "";

}

else{

if (!str.contains("0A")) {

str1 = str1+readStr;

}else{

if (!str.equals("0A")&&str.endsWith("0A")) {

mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_READ, bytes, -1, buffer)

.sendToTarget();

}

}

}

}

else

{

Log.e(TAG, "disconnected");

connectionLost();

if(mState != STATE_NONE)

{

Log.e(TAG, "disconnected");

BluetoothChatService.this.start();

}

break;

}

} catch (IOException e) {

Log.e(TAG, "disconnected", e);

connectionLost();

if(mState != STATE_NONE)

{

// 在重新启动监听模式启动该服务

BluetoothChatService.this.start();

}

break;

}

}

}

/**

* 写入OutStream连接

* @param buffer  要写的字节

*/

public void write(byte[] buffer) {

try {

mmOutStream.write(buffer);

// 把消息传给UI

mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_WRITE, -1, -1, buffer)

.sendToTarget();

} catch (IOException e) {

Log.e(TAG, "Exception during write", e);

}

}

public void cancel() {

try {

mmSocket.close();

} catch (IOException e) {

Log.e(TAG, "close() of connect socket failed", e);

}

}

}

/**

* 从字节数组到十六进制字符串转换

*/

public static String bytes2HexString(byte[] b) {

String ret = "";

for (int i = 0; i < b.length; i++) {

String hex = Integer.toHexString(b[ i ] & 0xFF);

if (hex.length() == 1) {

hex = '0' + hex;

}

ret += hex.toUpperCase();

}

return ret;

}

}

android 蓝牙ble调试助手,Android蓝牙调试助手源码分享相关推荐

  1. 基于java糖助手服务交流平台计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署

    基于java糖助手服务交流平台计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 基于java糖助手服务交流平台计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 本源码技术栈 ...

  2. [附源码]计算机毕业设计Python+uniapp基于Android校园二手交易平台设计与实现 o8k65(程序+源码+LW+远程部署)

    [附源码]计算机毕业设计Python+uniapp基于Android校园二手交易平台设计与实现 o8k65(程序+源码+LW+远程部署) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 ...

  3. [附源码]计算机毕业设计Python+uniapp基于android的古诗词鉴赏设计与实现lt9y0(程序+源码+LW+远程部署)

    [附源码]计算机毕业设计Python+uniapp基于android的古诗词鉴赏设计与实现lt9y0(程序+源码+LW+远程部署) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目 ...

  4. Android Jetpack架构组件之 Room(使用、源码篇)

    2019独角兽企业重金招聘Python工程师标准>>> 1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发 ...

  5. 【Android 插件化】Hook 插件化框架 ( 从源码角度分析加载资源流程 | Hook 点选择 | 资源冲突解决方案 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  6. Android 亲测源码分享

    Android 亲测源码分享 一.优质视频教程 1.老罗Android开发视频教程(更多经典教程制作进行中) http://www.apkbus.com/android-94796-1-1.html ...

  7. Android Glide图片加载框架(二)源码解析之into()

    文章目录 一.前言 二.源码解析 1.into(ImageView) 2.GlideContext.buildImageViewTarget() 3.RequestBuilder.into(Targe ...

  8. Android Glide图片加载框架(二)源码解析之load()

    文章目录 一.前言 二.源码分析 1.load() Android Glide图片加载框架系列文章 Android Glide图片加载框架(一)基本用法 Android Glide图片加载框架(二)源 ...

  9. Android Glide图片加载框架(二)源码解析之with()

    文章目录 一.前言 二.如何阅读源码 三.源码解析 1.with() Android Glide图片加载框架系列文章 Android Glide图片加载框架(一)基本用法 Android Glide图 ...

  10. android 活体识别人脸动作活体静默活体Demo源码实现讲解

    android 活体识别人脸动作活体静默活体Demo源码实现讲解 这里说活体是基于单目摄像头活体,适合所有普通安卓Android 单目摄像头的手机,双目的需要硬件支持,这里不讲述 . 百度网盘体验地址 ...

最新文章

  1. 新思科技助力IBM将AI计算性能提升1000倍
  2. 完全用Linux工作,抛弃windows
  3. ##API(七)————日期操作类(二)
  4. springMVC教程--拦截器详解
  5. public private protected
  6. amaze 绝对位置 html,Amaze UI 兼容性列表
  7. class(一)--类的创建
  8. Python文件的读取与写入
  9. nmap隐藏自己扫描
  10. 《火球——UML大战需求分析》(第3章 分析业务模型-类图)——3.7 关于对象图
  11. STL中的关联式容器——map(映射)
  12. Axure 8 - 中继器实战篇
  13. [思维][模拟]Scholomance Academy 第45届icpc区域赛沈阳站K
  14. Chrome添加扩展程序
  15. html如何制作电子邮件地址怎么写,如何制作html电子邮件?
  16. 计算机网络原理知识点及考点整理(谢希仁第七版)
  17. php写类,php 类的写法
  18. Tomcat报ClassFormatException: Invalid byte tag in constant pool: 19解决方法
  19. Steam Buff 自动选品 网页版教程
  20. 金额转换成大写和简称的方法

热门文章

  1. qcustomplot x轴当前时间_Qt使用QCustomPlot开发
  2. teambition/tower/team@osc/worktile团队协作工具价格比较
  3. excel中多列内容显示不全
  4. 【论文解读】Exploring Complementary Strengths of Invariant and Equivariant Representations(小样本等变和不变的互补)
  5. HL6601高性价比多种快充协议芯片QC3.0QC2.0华为FCP,SCP.VOOV苹果三星快充协议
  6. 循环语句介绍(笔记学习)
  7. 深入JUnit源码之Runner
  8. 【MATLAB】改变坐标轴范围
  9. Linux- 系统随你玩之--文件管理-双生姐妹花
  10. Linux meld安装