欢迎大家访问我的博客http://blog.csdn.net/mikejaps专注于android ios  app 开发


最近做蓝牙BLE的开发,此项目和网上别人的稍微有点不同,手机需要连接多个BLE设备,此部分网上的资料很少,所以拿出来和大家分享一下


//初始化
private void initBt() {manager = BluetoothManager.getInstance();manager.setContext(this);if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {Toast.makeText(this, "您的手机不支持BLE", Toast.LENGTH_SHORT).show();finish();}BluetoothAdapter btaAdapter = BluetoothAdapter.getDefaultAdapter();if (!btaAdapter.isEnabled()) {btaAdapter.enable();}if (!manager.isScanning)new ScanLeTask().execute();}

//扫描ble 设备
private class ScanLeTask extends AsyncTask {@Overrideprotected Void doInBackground(Void... params) {manager.scanLeDevice(true, mLeScanCallback);return null;}}// Device scan callback.private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {@Overridepublic void onLeScan(final BluetoothDevice device, int rssi,byte[] scanRecord) {runOnUiThread(new Runnable() {@Overridepublic void run() {Log.d(TAG, device.getName());BtDevice mDevice = new BtDevice(device.getAddress(),device.getName());if (!mList.contains(mDevice)) {mList.add(mDevice);View view = getLayoutInflater().inflate(R.layout.deviceitem, null);view.setTag(mList.size() - 1);TextView textView = (TextView) view.findViewById(R.id.name);Button button = (Button) view.findViewById(R.id.icon);button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {View view = (View) v.getParent();int index = (Integer) view.getTag();manager.connect(mList.get(index).getAddr(),index);Log.d(TAG, "index is:" + index);}});textView.setText(mDevice.getName());container.addView(view);}}});}};

//封装的核心类
public class BluetoothManager {protected static final String TAG = "BluetoothManager";private Context context;public boolean isScanning;private int index;private Handler handler = new Handler();// 10秒后停止查找搜索.private static final long SCAN_PERIOD = 10000;private static BluetoothAdapter btaAdapter = BluetoothAdapter.getDefaultAdapter();// public static BluetoothGatt mBluetoothGatt;private int disconStatus;public final static String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED";public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);private static BluetoothManager instance;private BluetoothManager() {}public static BluetoothManager getInstance() {if (instance == null) {synchronized (BluetoothManager.class) {if (instance == null) {instance = new BluetoothManager();}}}return instance;}public void setContext(Context mContext) {context = mContext;}private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {@Overridepublic void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) {if (newState == BluetoothProfile.STATE_CONNECTED) {Log.d(TAG, "Connected to GATT server.");// Attempts to discover services after successful connection.Log.d(TAG,"Attempting to start service discovery:"+ gatt.discoverServices());} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {Log.d(TAG, "Disconnected from GATT server.");if (disconStatus == 129) {close(gatt);Log.d(TAG, "----129----");btaAdapter.disable();try {Thread.sleep(2500);} catch (InterruptedException e) {e.printStackTrace();}btaAdapter.enable();}}}@Overridepublic void onServicesDiscovered(BluetoothGatt gatt, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {if (gatt == null)return;// writeData(gatt, new byte[] { 0x11, 0x12 });// displayGattServices(gatt.getServices());Log.d(TAG, "BluetoothGatt.GATT_SUCCESS");} else {Log.d(TAG, "onServicesDiscovered received: " + status);disconStatus = status;}}@Overridepublic void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {// broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);Log.d(TAG, "onCharacteristicRead");// Toast.makeText(BluetoothLeService.this,// "onCharacteristicRead successfully", 100).show();}}@Overridepublic void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {// broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);Log.d(TAG, "onCharacteristicChanged");}};public void writeData(BluetoothGatt gatt, byte[] datas) {if (/* btaAdapter == null || */gatt == null) {Log.w(TAG, "BluetoothGatt is null  can not writeData.");return;}BluetoothGattService gattService = gatt.getService(UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT));if (gattService == null) {Log.w(TAG,"the gattService for BluetoothGattService is null,can not write data");return;}BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));if (characteristic == null) {Log.w(TAG,"the uuid for BluetoothGattCharacteristic is null,can not write data");return;}characteristic.setValue(datas);// gatt.writeCharacteristic(characteristic);Log.i(TAG,"writeCharacteristic"+ gatt.writeCharacteristic(characteristic));}/** * Enables or disables notification on a give characteristic. *  * @param characteristic *            Characteristic to act on. * @param enabled *            If true, enable notification. False otherwise. */public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {BluetoothGatt gatt = MainActivity.mList.get(index).getmBluetoothGatt();if (btaAdapter == null || gatt == null) {Log.w(TAG, "BluetoothAdapter not initialized");return;}gatt.setCharacteristicNotification(characteristic, enabled);// This is specific to Heart Rate Measurement.if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);gatt.writeDescriptor(descriptor);}}private boolean isPrepared;public void scanLeDevice(final boolean enable,final BluetoothAdapter.LeScanCallback mLeScanCallback) {if (!isPrepared) {isPrepared = true;Looper.prepare();}if (enable) {// Stops scanning after a pre-defined scan period.handler.postDelayed(new Runnable() {@Overridepublic void run() {isScanning = false;btaAdapter.stopLeScan(mLeScanCallback);Log.d(TAG, "STOP....");}}, SCAN_PERIOD);isScanning = true;btaAdapter.startLeScan(mLeScanCallback);} else {isScanning = false;btaAdapter.stopLeScan(mLeScanCallback);}}/** * After using a given BLE device, the app must call this method to ensure * resources are released properly. */public void close(BluetoothGatt gatt) {if (gatt == null) {return;}gatt.close();gatt = null;}/** * Connects to the GATT server hosted on the Bluetooth LE device. *  * @param address *            The device address of the destination device. *  * @return Return true if the connection is initiated successfully. The *         connection result is reported asynchronously through the *         {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} *         callback. */public boolean connect(final String address, int index) {this.index = index;if (address == null) {Log.w(TAG, " unspecified address.");return false;}final BluetoothDevice device = btaAdapter.getRemoteDevice(address);if (device == null) {Log.w(TAG, "Device not found.  Unable to connect.");return false;}// We want to directly connect to the device, so we are setting the// autoConnect// parameter to false.// MainActivity.mList.get(index).setmBluetoothGatt(gatt);if (!MainActivity.gattMap.containsKey(MainActivity.mList.get(index).getAddr())) {BluetoothGatt gatt = device.connectGatt(context, true,mGattCallback);MainActivity.gattMap.put(MainActivity.mList.get(index).getAddr(),gatt);Log.d(TAG, "Trying to create a new connection."+ MainActivity.gattMap.size());} elseLog.d(TAG, "allready connected." + MainActivity.gattMap.size());return true;}/** * Disconnects an existing connection or cancel a pending connection. The * disconnection result is reported asynchronously through the * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} * callback. */public void disconnect(int index) {if (btaAdapter == null) {Log.w(TAG, "BluetoothAdapter not initialized");return;}MainActivity.mList.get(index).getmBluetoothGatt().disconnect();}}

//用于发送数据的线程池
public class BluetoothExecutor {private static final String TAG = "TcpExecutor";private static BluetoothExecutor instance = null;private ThreadPoolExecutor executor;private Semaphore semp;private BluetoothManager manager;private BluetoothExecutor() {executor = new ThreadPoolExecutor(1, 7, 500, TimeUnit.MILLISECONDS,new ArrayBlockingQueue(20));semp = new Semaphore(1);manager = BluetoothManager.getInstance();}public static BluetoothExecutor getInstans() {if (instance == null) {synchronized (BluetoothExecutor.class) {if (instance == null)instance = new BluetoothExecutor();}}return instance;}public void execute(final byte[] chars) {Log.d(TAG, "execute start" + executor.getActiveCount());try {semp.acquire();final Set set = MainActivity.gattMap.keySet();Log.d(TAG, "Set" + set);for (int i = 0; i < MainActivity.gattMap.size(); i++) {executor.execute(new Runnable() {@Overridepublic void run() {manager.writeData(MainActivity.gattMap.get(set.iterator().next()),chars);}});}while (executor.getActiveCount() != 0);semp.release();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}


更多相关文章

  1. Android开发四年面试相关知识整理
  2. 基于Intel x86 Android的RAD游戏开发
  3. 三、Android中的显示单位
  4. 【安卓开发学习】6.ListView点击事…
  5. 【Android2D游戏开发之四】Android(安卓)游戏框架(一个游戏角色在
  6. ubuntu10.10 下安装android 2.2开发环境
  7. Android(安卓)SDK 2.3与Eclipse最新版开发环境搭建(二)
  8. Android(安卓)游戏开发必备的基础知识
  9. 关于如何高效率开发一个Android(安卓)App

随机推荐

  1. Android(安卓)11 正式发布 | 开发者们的
  2. android studio启动一直卡在fetching And
  3. 解决Android启动显示空白界面的问题,自定
  4. Viewpager2—登录注册引导页面
  5. Android(安卓)自定义 RadioButton 去除无
  6. 关于 Android合并分区的问题
  7. Android(安卓)Studio安装配置详细步骤(超
  8. Android(安卓)定位GPS的使用
  9. 2020年GitHub标星2.9K的Android基础——
  10. Android(安卓)style & Theme 再探析(一)