1、添加蓝牙权限
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
2、获取本地蓝牙适配器
通过本地蓝牙适配器可以做以下一系列操作
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
3、手机是否支持蓝牙
蓝牙适配器不为空,则支持蓝牙
/**
* 是否支持蓝牙
* @return
*/
public boolean isSupportBlueTooth(){
if(mAdapter != null){
return true;
}
return false;
}
4、蓝牙是否打开
/**
* 蓝牙是否打开
* @return
*/
public boolean getBlueToothStatus(){
if(mAdapter != null){
return mAdapter.isEnabled();
}
return false;
}
5、蓝牙打开与关闭
/**
* 打开蓝牙
* @param activity
* @param requestCode 用于onActivityResult中判断
*/
public void turnOnBlueTooth(Activity activity, int requestCode){
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(intent, requestCode);
// google不建议直接打开 mAdapter.enable();
}
/**
* 关闭蓝牙
*/
public void turnOffBlueTooth() {
mAdapter.disable();
}
6、处理返回状态
蓝牙的打开关闭等状态通过广播和Activity返回
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 蓝牙状态广播
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
switch (state){
case BluetoothAdapter.STATE_OFF:
showToast("broadcast-->蓝牙关闭");
break;
case BluetoothAdapter.STATE_ON:
showToast("broadcast-->蓝牙打开");// 真机测试此处未执行,在Activity的回调中执行
break;
case BluetoothAdapter.STATE_TURNING_ON:
showToast("broadcast-->蓝牙正在打开");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
showToast("broadcast-->蓝牙正在关闭");
break;
default:
showToast("未知状态");
break;
}
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
showToast("打开成功");
}else{
showToast("打开失败");
}
}
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
7、其他功能
以上是蓝牙最基础的判断,下面介绍连接、绑定等功能
7.1设置可见
通过Intent设置可见
/**
* 打开蓝牙可见
* @param activity
*/
public void enableVisibly(Activity activity){
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
// 蓝牙可见时间300秒
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
activity.startActivity(intent);
}
注册广播监听
// 这个蓝牙状态的监听,供参考
// IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
//设备扫描模式改变,可见监听 filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
广播中处理
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// 是否可见监听
if( BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
int scanMode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,0);
if( scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
showToast("可见");
}
else {
showToast("不可见");
}
}
// 蓝牙状态广播 // int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
7.2扫描设备
// 查找设备,点击绑定
case R.id.find_device:
mAdapter.refresh(mDeviceList);
mController.findDevice();
mListView.setOnItemClickListener(bindDeviceClick);
break;
//开始查找
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
//结束查找
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//查找设备
filter.addAction(BluetoothDevice.ACTION_FOUND);
// 开始扫描
if( BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action) ) {
//初始化数据列表
showToast("开始扫描");
mDeviceList.clear();
mAdapter.notifyDataSetChanged();
}
// 扫描完成
if( BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
showToast("扫描完成");
}
// 发现设备
if( BluetoothDevice.ACTION_FOUND.equals(action)) {
showToast("发现设备");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//找到一个,添加一个
mDeviceList.add(device);
mAdapter.notifyDataSetChanged();
}
7.3绑定设备
/**
* 绑定设备
*/
private AdapterView.OnItemClickListener bindDeviceClick = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
BluetoothDevice device = mDeviceList.get(position);
// android 4.4才支持应用绑定蓝牙
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
device.createBond();
}else{
try {
createBond(device.getClass(), device);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
/**
* 与设备配对 参考源码:platform/packages/apps/Settings.git
* /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
*/
static public boolean createBond(Class btClass,BluetoothDevice btDevice) throws Exception {
Method createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
/**
* 与设备解除配对 参考源码:platform/packages/apps/Settings.git
* /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
*/
static public boolean removeBond(Class btClass,BluetoothDevice btDevice) throws Exception {
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
// 绑定状态监听
if( BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action) ) {
BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if( remoteDevice == null ) {
showToast("没有设备");
return;
}
int status = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,0);
if( status == BluetoothDevice.BOND_BONDED) {
showToast("已绑定 " + remoteDevice.getName());
}
else if( status == BluetoothDevice.BOND_BONDING){
showToast("绑定中 " + remoteDevice.getName());
}
else if(status == BluetoothDevice.BOND_NONE){
showToast("未绑定 " + remoteDevice.getName());
}
}
}
7.4连接设备
/**
* 连接设备
*/
private AdapterView.OnItemClickListener bindedDeviceClick = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BluetoothDevice device = mBondedDeviceList.get(i);
ChatController.getInstance().startChatWith(device, mController.getAdapter(), mUIHandler);
}
};
7.5三个线程
package com.example.bluetoothchat.connect;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import java.io.IOException;
import java.util.UUID;
/**
* 服务端等待连接线程
* Created by Administrator on 2015/7/3.
*/
public class AcceptThread extends Thread {
private static final String NAME = "BlueTooth";
private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
private final BluetoothAdapter mBluetoothAdapter;
private final Handler mHandler;
private final BluetoothServerSocket mServerSocket;
private ConnectedThread mConnectedThread;
/**
* 服务端线程构造器,包括创建服务端的Socket
* @param adapter
* @param handler
*/
public AcceptThread(BluetoothAdapter adapter, Handler handler) {
mBluetoothAdapter = adapter;
mHandler = handler;
BluetoothServerSocket tmp = null;
try {
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
mServerSocket = tmp;
}
@Override
public void run() {
// 直到发生异常前,一直监听客户端的连接
BluetoothSocket socket = null;
while(true){
try {
mHandler.sendEmptyMessage(Constant.MSG_START_LISTENING);
socket = mServerSocket.accept();
} catch (IOException e) {
mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, e));
break;
}
// 有连接接收
if(socket != null){
manageConnectedSocket(socket);
try {
mServerSocket.close();
mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
/**
* 管理Socket连接,只支持一个连接
* @param socket
*/
private void manageConnectedSocket(BluetoothSocket socket){
if(mConnectedThread != null){
mConnectedThread.cancel();
}
mHandler.sendEmptyMessage(Constant.MSG_GOT_A_CLINET);
mConnectedThread = new ConnectedThread(socket, mHandler);
mConnectedThread.start();
}
/**
* 关闭socket
*/
public void cancel(){
try {
mServerSocket.close();
mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发生数据
* @param data
*/
public void sendData(byte[] data){
if(mConnectedThread != null){
mConnectedThread.write(data);
}
}
}
package com.example.bluetoothchat.connect;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import java.io.IOException;
import java.util.UUID;
/**
* 客户端线程连接
* Created by Administrator on 2015/7/3.
*/
public class ConnectThread extends Thread{
private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
private final BluetoothDevice mDevice;
private final BluetoothAdapter mBluetoothAdapter;
private final Handler mHandler;
private final BluetoothSocket mSocket;
private ConnectedThread mConnectedThread;
public ConnectThread(BluetoothDevice device, BluetoothAdapter adapter, Handler handler){
BluetoothSocket tmp = null;
mDevice = device;
mBluetoothAdapter = adapter;
mHandler = handler;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
mSocket = tmp;
}
@Override
public void run() {
// 连接后不再需要扫描了
mBluetoothAdapter.cancelDiscovery();
try {
mSocket.connect();
} catch (IOException e) {
mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR));
try {
mSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return;
}
// 管理Socket连接
manageConnectedSocket(mSocket);
}
private void manageConnectedSocket(BluetoothSocket mSocket) {
mHandler.sendEmptyMessage(Constant.MSG_CONNECTED_TO_SERVER);
mConnectedThread = new ConnectedThread(mSocket, mHandler);
mConnectedThread.start();
}
public void cancel(){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendData(byte[] data){
if(mConnectedThread != null){
mConnectedThread.write(data);
}
}
}
package com.example.bluetoothchat.connect;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 连接线程
* Created by Administrator on 2015/7/3.
*/
public class ConnectedThread extends Thread{
private final BluetoothSocket mSocket;
private final Handler mHandler;
private final InputStream mInStream;
private final OutputStream mOutStream;
public ConnectedThread(BluetoothSocket socket, Handler handler) {
mSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
mHandler = handler;
// 获取Socket的输入输出流
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mInStream = tmpIn;
mOutStream = tmpOut;
}
@Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true){
try {
bytes = mInStream.read(buffer);
if(bytes > 0){
Log.d("r","===");
Message message = mHandler.obtainMessage(Constant.MSG_GOT_DATA, buffer);
mHandler.sendMessage(message);
}
Log.d("r", "message size" + bytes);
} catch (IOException e) {
e.printStackTrace();
mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, e));
break;
}
}
}
/**
* 关闭连接
*/
public void cancel() {
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 写数据
* @param data
*/
public void write(byte[] data) {
try {
mOutStream.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}