1.如果你准备搞蓝牙开发了,那么Android的基本常识你也应该很熟悉,比如说:Service 。你还需要一个支持蓝牙4.0的手机,不然神马都白瞎! 首先,几乎所有的蓝牙开发都是基于服务的,那么你需要建立一个蓝牙服务类。 像这样public class BluetoothService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
startService(new Intent(this,BluetoothService.class));
2.服务建立好之后,我们要初始化蓝牙(2B青年都知道初始化蓝牙的前提是你必须开启手机的蓝牙,申请蓝牙所需要的权限),我比较喜欢在onCreate方法中初始化,网上有很多很多的方法,我想说的是:能搞出来就行了,你就牛逼了
上面是申请权限,我就不解释了, 然后
初始化蓝牙,当然你也可以在Activity中
判断蓝牙是否可用,或者是否启动
import android.annotation.SuppressLint;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Intent;
import android.os.IBinder;
public class BluetoothService extends Service {
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@SuppressLint("NewApi")
@Override
public void onCreate() {
// TODO Auto-generated method stub
bluetoothManager=(BluetoothManager)getSystemService(Service.BLUETOOTH_SERVICE);
// 这个方法属于新API,我的eclipse中也报错,按eclipse提示修改
bluetoothAdapter=bluetoothManager.getAdapter();
// 若蓝牙为打开,就会提示用户启动蓝牙服务
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(enableBtIntent);
return;
}
super.onCreate();
}
}
3.我们启动了蓝牙服务,光有蓝牙没有设备那是瞎掰,我们需要搜索周围的设备,一般是搜索一段时间之后自动停止搜索。如果你从我大天朝地大物博,物产丰富的角度考虑的话,你可以让你的手机一直搜索设备,毕竟我们天朝有的是能源。蓝牙适配器给我们提供了一个搜索方法:bluetoothAdapter.startLeScan(callback) 很显然callBack是个回调,是一个 BluetoothAdapter.LeScanCallback的回调 ,我是最受不了这种回调了,一大坨,看得蛋疼,这里不得不说objective-c了,objective-c最大的好处是你可以让所有的方法平行,那么很明显,我们需要调用startLeScan()必须实例化一个LeScanCallback的类且覆写回调函数。上代码
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public class BluetoothService extends Service {
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private Handler handler;
private boolean scanning;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@SuppressLint("NewApi")
@Override
public void onCreate() {
// TODO Auto-generated method stub
bluetoothManager=(BluetoothManager)getSystemService(Service.BLUETOOTH_SERVICE);
// 这个方法属于新API,我的eclipse中也报错,按eclipse提示修改
bluetoothAdapter=bluetoothManager.getAdapter();
// 若蓝牙为打开,就会提示用户启动蓝牙服务
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(enableBtIntent);
return;
}
handler=new Handler();
super.onCreate();
}
private void startFindDevice() {
if (!bluetoothAdapter.isDiscovering()) {
scanLeDevice(true);
}
}
public void stopFindDevice() {
scanLeDevice(false);
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
handler.postDelayed(new Runnable() {
@Override
public void run() {
scanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}, 10000);
scanning = true;
bluetoothAdapter.startLeScan(leScanCallback);
} else {
scanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}
BluetoothAdapter.LeScanCallback leScanCallback=new BluetoothAdapter.LeScanCallback(){
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] arg2) {
// TODO Auto-generated method stub
// device 搜索到的设备
// rssi 设备的rssi 也就是当前的设备信号的强弱
}
};
}
我们现在
可以找到附近的蓝牙设备,且能够获取到搜索的时候的瞬间的设备信号大小,但是问题来了?这些所有的操作都是在服务里面,如何与
你所在的Activity通信了,添加广播和广播接受者,不用我想起说了,想知道私信。
4.找到设备之后,我们需要连接设备,并且将已经连接上的设备保存起来,通常硬件设备都有一个唯一的MAC地址,连接硬件的方法是bluetoothDevice.connectGatt(context, autoConnect, callback), 第二个参数重点说下,一般是false,如果是写true设备会自动重新连接的,第三个参数又是个蛋疼的回调BluetoothGattCallback(这里面有很多牛逼的方法,这是蓝牙通信的核心),一般要动态的读取rssi的值很明显你要马不停蹄的读取,从成功连接到设备开始,我们开始搞起, gatt.readRemoteRssi() 这是读取远程蓝牙设备的rssi值,是一个循环读取的过程
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public class BluetoothService extends Service {
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private Handler handler;
private boolean scanning;
private Map bluetoothGattMap;
private Timer mRssiTimer;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@SuppressLint("NewApi")
@Override
public void onCreate() {
// TODO Auto-generated method stub
bluetoothManager=(BluetoothManager)getSystemService(Service.BLUETOOTH_SERVICE);
// 这个方法属于新API,我的eclipse中也报错,按eclipse提示修改
bluetoothAdapter=bluetoothManager.getAdapter();
// 若蓝牙为打开,就会提示用户启动蓝牙服务
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(enableBtIntent);
return;
}
bluetoothGattMap=new HashMap();
handler=new Handler();
super.onCreate();
}
private void startFindDevice() {
if (!bluetoothAdapter.isDiscovering()) {
scanLeDevice(true);
}
}
public void stopFindDevice() {
scanLeDevice(false);
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
handler.postDelayed(new Runnable() {
@Override
public void run() {
scanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}, 10000);
scanning = true;
bluetoothAdapter.startLeScan(leScanCallback);
} else {
scanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}
BluetoothAdapter.LeScanCallback leScanCallback=new BluetoothAdapter.LeScanCallback(){
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] arg2) {
// TODO Auto-generated method stub
// device 搜索到的设备
// rssi 设备的rssi 也就是当前的设备信号的强弱
}
};
private boolean connect(String address) {
stopFindDevice();
if ((bluetoothAdapter == null) || (address == null)) {
return false;
}
BluetoothGatt gatt = (BluetoothGatt) bluetoothGattMap.get(address);
if (gatt != null) {
gatt.close();
}
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
if (device == null) {
return false;
}
gatt = device.connectGatt(this, false, bluetoothGattCallback);
bluetoothGattMap.put(address, gatt);
return true;
}
public boolean disconnect(String address) {
BluetoothGatt gatt = (BluetoothGatt) bluetoothGattMap.get(address);
if (gatt != null) {
gatt.close();
}
bluetoothGattMap.remove(address);
return true;
}
BluetoothGattCallback bluetoothGattCallback=new BluetoothGattCallback(){
@Override
public void onConnectionStateChange(final BluetoothGatt gatt,
int status, int newState) {
// TODO Auto-generated method stub
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
TimerTask task = new TimerTask() {
@Override
public void run() {
// 我不停的读取,不停的读取,时间频率自己控制就行
gatt.readRemoteRssi();
}
};
mRssiTimer = new Timer();
mRssiTimer.schedule(task, 1000, 1000);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
if (mRssiTimer != null) {
mRssiTimer.cancel();
}
}
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
// 动态获取 rssi 值
}
};
}
注意:
是rssi的值需要不停的循环读取的,这是一个长连接
5.获取蓝牙的特征值,也就是蓝牙那个模块可写可读,我一般是蓝牙连接成功之后调用发现服务方法gatt.discoverServices();
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public class BluetoothService extends Service {
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private Handler handler;
private boolean scanning;
private Map bluetoothGattMap;
private Timer mRssiTimer;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@SuppressLint("NewApi")
@Override
public void onCreate() {
// TODO Auto-generated method stub
bluetoothManager=(BluetoothManager)getSystemService(Service.BLUETOOTH_SERVICE);
// 这个方法属于新API,我的eclipse中也报错,按eclipse提示修改
bluetoothAdapter=bluetoothManager.getAdapter();
// 若蓝牙为打开,就会提示用户启动蓝牙服务
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(enableBtIntent);
return;
}
bluetoothGattMap=new HashMap();
handler=new Handler();
super.onCreate();
}
private void startFindDevice() {
if (!bluetoothAdapter.isDiscovering()) {
scanLeDevice(true);
}
}
public void stopFindDevice() {
scanLeDevice(false);
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
handler.postDelayed(new Runnable() {
@Override
public void run() {
scanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}, 10000);
scanning = true;
bluetoothAdapter.startLeScan(leScanCallback);
} else {
scanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}
BluetoothAdapter.LeScanCallback leScanCallback=new BluetoothAdapter.LeScanCallback(){
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] arg2) {
// TODO Auto-generated method stub
// device 搜索到的设备
// rssi 设备的rssi 也就是当前的设备信号的强弱
}
};
private boolean connect(String address) {
stopFindDevice();
if ((bluetoothAdapter == null) || (address == null)) {
return false;
}
BluetoothGatt gatt = (BluetoothGatt) bluetoothGattMap.get(address);
if (gatt != null) {
gatt.close();
}
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
if (device == null) {
return false;
}
gatt = device.connectGatt(this, false, bluetoothGattCallback);
bluetoothGattMap.put(address, gatt);
return true;
}
public boolean disconnect(String address) {
BluetoothGatt gatt = (BluetoothGatt) bluetoothGattMap.get(address);
if (gatt != null) {
gatt.close();
}
bluetoothGattMap.remove(address);
return true;
}
BluetoothGattCallback bluetoothGattCallback=new BluetoothGattCallback(){
@Override
public void onConnectionStateChange(final BluetoothGatt gatt,
int status, int newState) {
// TODO Auto-generated method stub
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
// 连接成功时获取特征值
gatt.discoverServices();
TimerTask task = new TimerTask() {
@Override
public void run() {
// 我不停的读取,不停的读取,时间频率自己控制就行
gatt.readRemoteRssi();
}
};
mRssiTimer = new Timer();
mRssiTimer.schedule(task, 1000, 1000);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
if (mRssiTimer != null) {
mRssiTimer.cancel();
}
}
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
// 动态获取 rssi 值
}
@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
showService(gatt.getServices());
} else {
}
}
};
private void showService(List list){
if (list == null) return;
for (BluetoothGattService gattService : list) {
List gattCharacteristics =gattService.getCharacteristics();
for ( final BluetoothGattCharacteristic gattCharacteristic: gattCharacteristics) {
if(gattCharacteristic.getUuid().toString().equalsIgnoreCase("0000fff1-0000-1000-8000-00805f9b34fb")){
// 这是我的特征值
}
}
}
}
}
注意我的最下面的一个方法,获取到这个特征值之后,便可以在里面写入数据了6.写入数据,上代码中....看最后
import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.content.Intent; import android.os.Build; import android.os.Handler; import android.os.IBinder; @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public class BluetoothService extends Service { private BluetoothManager bluetoothManager; private BluetoothAdapter bluetoothAdapter; private Handler handler; private boolean scanning; private MapbluetoothGattMap; private Timer mRssiTimer; private ExecutorService readWriteWorker = Executors.newSingleThreadExecutor(); private volatile BluetoothGattCharacteristic bluetoothGattCharacteristic; private volatile BluetoothGatt bluetoothGatt; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @SuppressLint("NewApi") @Override public void onCreate() { // TODO Auto-generated method stub bluetoothManager=(BluetoothManager)getSystemService(Service.BLUETOOTH_SERVICE); // 这个方法属于新API,我的eclipse中也报错,按eclipse提示修改 bluetoothAdapter=bluetoothManager.getAdapter(); // 若蓝牙为打开,就会提示用户启动蓝牙服务 if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(enableBtIntent); return; } bluetoothGattMap=new HashMap (); handler=new Handler(); super.onCreate(); } private void startFindDevice() { if (!bluetoothAdapter.isDiscovering()) { scanLeDevice(true); } } public void stopFindDevice() { scanLeDevice(false); } private void scanLeDevice(final boolean enable) { if (enable) { // Stops scanning after a pre-defined scan period. handler.postDelayed(new Runnable() { @Override public void run() { scanning = false; bluetoothAdapter.stopLeScan(leScanCallback); } }, 10000); scanning = true; bluetoothAdapter.startLeScan(leScanCallback); } else { scanning = false; bluetoothAdapter.stopLeScan(leScanCallback); } } BluetoothAdapter.LeScanCallback leScanCallback=new BluetoothAdapter.LeScanCallback(){ @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] arg2) { // TODO Auto-generated method stub // device 搜索到的设备 // rssi 设备的rssi 也就是当前的设备信号的强弱 } }; private boolean connect(String address) { stopFindDevice(); if ((bluetoothAdapter == null) || (address == null)) { return false; } BluetoothGatt gatt = (BluetoothGatt) bluetoothGattMap.get(address); if (gatt != null) { gatt.close(); } BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address); if (device == null) { return false; } gatt = device.connectGatt(this, false, bluetoothGattCallback); bluetoothGattMap.put(address, gatt); return true; } public boolean disconnect(String address) { BluetoothGatt gatt = (BluetoothGatt) bluetoothGattMap.get(address); if (gatt != null) { gatt.close(); } bluetoothGattMap.remove(address); return true; } BluetoothGattCallback bluetoothGattCallback=new BluetoothGattCallback(){ @Override public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) { // TODO Auto-generated method stub super.onConnectionStateChange(gatt, status, newState); if (newState == BluetoothProfile.STATE_CONNECTED) { // 连接成功时获取特征值 gatt.discoverServices(); TimerTask task = new TimerTask() { @Override public void run() { // 我不停的读取,不停的读取,时间频率自己控制就行 gatt.readRemoteRssi(); } }; mRssiTimer = new Timer(); mRssiTimer.schedule(task, 1000, 1000); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { if (mRssiTimer != null) { mRssiTimer.cancel(); } } } @Override public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { // 动态获取 rssi 值 } @Override // New services discovered public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { bluetoothGatt=gatt; showService(gatt.getServices()); } else { } } }; private void showService(List list){ if (list == null) return; for (BluetoothGattService gattService : list) { List gattCharacteristics =gattService.getCharacteristics(); for ( final BluetoothGattCharacteristic gattCharacteristic: gattCharacteristics) { if(gattCharacteristic.getUuid().toString().equalsIgnoreCase("0000fff1-0000-1000-8000-00805f9b34fb")){ // 这是我的特征值 } } } } private void writeData(){ byte[] value = new byte[]{(byte) 0x01,(byte) 0x01,(byte) 0x01,(byte) 0x01}; bluetoothGattCharacteristic.setValue(value); bluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic); } }