javaee论坛

普通会员

225648

帖子

337

回复

351

积分

楼主
发表于 2017-06-10 06:10:23 | 查看: 874 | 回复: 1

< name="code" class="java"></>1.如果你准备搞蓝牙开发了,那么Android的基本常识你也应该很熟悉,比如说:<span style="font-size:18px;"><span style="color:#ff0000;">Service 。你还需要一个支持蓝牙4.0的手机,不然神马都白瞎! </span>首先,几乎所有的蓝牙开发都是基于服务的,那么你需要建立一个蓝牙服务类。 像这样</span><p></p><p><span style="font-size:18px;">public class BluetoothService extends Service {</span></p><p></p>< name="code" class="java"><span style="font-size:18px;"> @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; }}</span>
当然,服务需要在AndroidManifest中注册的,然后在恰当的时候(很显然,是在你恰当的时候)启动服务 

startService(new Intent(this,BluetoothService.class));

< name="code" class="html"> <service android:name="com.hebiao.blutoothtest.BluetoothService" android:enabled="true" android:exported="false" />

2.服务建立好之后,我们要初始化蓝牙(2B青年都知道初始化蓝牙的前提是你必须开启手机的蓝牙,申请蓝牙所需要的权限),我比较喜欢在onCreate方法中初始化,网上有很多很多的方法,我想说的是:能搞出来就行了,你就牛逼了

< name="code" class="html"> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />上面是申请权限,我就不解释了, 然后初始化蓝牙,当然你也可以在Activity中判断蓝牙是否可用,或者是否启动

< name="code" class="java">import android.annotation.SupssLint;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; } @SupssLint("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的类且覆写回调函数。上代码

< name="code" class="java">import android.annotation.SupssLint;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; } @SupssLint("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 -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值,是一个循环读取的过程

< name="code" class="java">import java.util.HashMap;import java.util.Map;import java.util.Timer;import java.util.TimerTask;import android.annotation.SupssLint;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<String, BluetoothGatt> bluetoothGattMap; private Timer mRssiTimer; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @SupssLint("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<String, BluetoothGatt>(); 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 -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();< name="code" class="java">import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Timer;import java.util.TimerTask;import android.annotation.SupssLint;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<String, BluetoothGatt> bluetoothGattMap; private Timer mRssiTimer; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @SupssLint("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<String, BluetoothGatt>(); 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 -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<BluetoothGattService> list){ if (list == null) return; for (BluetoothGattService gattService : list) { List<BluetoothGattCharacteristic> gattCharacteristics =gattService.getCharacteristics(); for ( final BluetoothGattCharacteristic gattCharacteristic: gattCharacteristics) { if(gattCharacteristic.getUuid().toString().equalsIgnoreCase("0000fff1-0000-1000-8000-00805f9b34fb")){// 这是我的特征值 } } } }}


< name="code" class="java"></><span style="color:#cc0000;">注意我的最下面的一个方法,获取到这个特征值之后,便可以在里面写入数据了</span><p></p><p><span style="font-size:18px;"><span style="color:#cc0000;"></span></span></p><p><span style="font-size:18px;">6.写入数据,上代码中....看最后</span></p><p>< name="code" class="java" style="font-size: 18px;">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.SupssLint;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<String, BluetoothGatt> bluetoothGattMap; 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; } @SupssLint("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<String, BluetoothGatt>(); 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 -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<BluetoothGattService> list){ if (list == null) return; for (BluetoothGattService gattService : list) { List<BluetoothGattCharacteristic> 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); } }
实际开发中还会遇到一个问题,就是读取多个设备的rssi值!元芳,你怎么看? 



 




 



普通会员

0

帖子

287

回复

292

积分
沙发
发表于 2019-11-13 21:15:56

专业抢二楼!顺便笑摸狗头(3L)

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017