android 手机与蓝牙设备的通讯
来源:互联网 发布:access数据录入窗体 编辑:程序博客网 时间:2024/04/27 19:46
1.首先创建个Activity来搜索蓝牙低耗设备
package com.example.xxx;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothManager;import android.bluetooth.le.BluetoothLeScanner;import android.bluetooth.le.ScanCallback;import android.bluetooth.le.ScanResult;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.os.Build;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import com.example.xxx.R;import java.util.ArrayList;import java.util.List;public class DeviceListActivity extends Activity { private BluetoothAdapter mBluetoothAdapter; private BluetoothAdapter.LeScanCallback mLeScanCallback; private ScanCallback mBleScanCallback; private ArrayAdapter<String> mNewDevicesArrayAdapter; private ListView pairedListView; private BluetoothDevice device; private Button scanButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_LEFT_ICON); setContentView(R.layout.device_list); setResult(Activity.RESULT_CANCELED); getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.actionbar_statuson_icon); getWindow().setBackgroundDrawableResource(R.color.bg); getWindow().setTitleColor(getResources().getColor(R.color.white)); scanButton = (Button) findViewById(R.id.button_scan); scanButton.setVisibility(View.GONE); mNewDevicesArrayAdapter = new ArrayAdapter<String>(DeviceListActivity.this, R.layout.listview_bluetoothdevicename); pairedListView = (ListView) findViewById(R.id.paired_devices); pairedListView.setOnItemClickListener(mDeviceClickListener); if (!DeviceListActivity.this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { showToas("设备不支持蓝牙功能"); return; } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { BluetoothManager mBluetoothManager = (BluetoothManager) DeviceListActivity.this.getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = mBluetoothManager.getAdapter(); if (mBluetoothAdapter == null) { showToas("设备不支持蓝牙功能"); return; } if (!mBluetoothAdapter.isEnabled()) { mBluetoothAdapter.enable(); //开启 return; } scanButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { scanButton.setVisibility(View.GONE); init(); } }); init(); } } /** * 初始化 */ private void init() { // 开始搜索 setTitle(R.string.scanning); setProgressBarIndeterminateVisibility(true); scanLeDevice(true); } /** * 是否开始扫描 * * @param enable true 为 是 */ private void scanLeDevice(final boolean enable) { if (mBluetoothAdapter == null) { BluetoothManager mBluetoothManager = (BluetoothManager) DeviceListActivity.this.getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = mBluetoothManager.getAdapter(); } if (enable) { // 开始扫描 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (mBleScanCallback == null) { initScanCallback(); } // 5.0 扫描 BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); if (bluetoothLeScanner != null) { bluetoothLeScanner.startScan(mBleScanCallback); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { // 4.3 扫描 if (mLeScanCallback == null) { initLeScanCallback(); } mBluetoothAdapter.startLeScan(mLeScanCallback); } } else { // 停止扫描 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (mBluetoothAdapter != null && mBleScanCallback != null) { BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); if (bluetoothLeScanner != null) { bluetoothLeScanner.stopScan(mBleScanCallback); } } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (mBluetoothAdapter != null && mLeScanCallback != null) { mBluetoothAdapter.stopLeScan(mLeScanCallback); } } } } /** * 初始化 Android 5.0 以下 4.3 以上蓝牙搜索结果类 */ List<String> list = new ArrayList<>(); private void initLeScanCallback() { mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { // 搜索到设备了 if (Math.abs(rssi) <= 90) {//过滤掉信号强度小于-90的设备 String deviceName = device.getName(); if (!StringUtils.isEmpty(deviceName) && !list.contains(device.getName() + "\n" + device.getAddress())&&(deviceName.contains("bluetooth-name01")||deviceName.contains("bluetooth-name02"))) { list.add(device.getName() + "\n" + device.getAddress()); mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); pairedListView.setAdapter(mNewDevicesArrayAdapter); mNewDevicesArrayAdapter.notifyDataSetChanged(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 停止扫描 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (mBluetoothAdapter != null && mBleScanCallback != null) { BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); if (bluetoothLeScanner != null) { bluetoothLeScanner.stopScan(mBleScanCallback); setProgressBarIndeterminateVisibility(false); setTitle(R.string.select_device); scanButton.setVisibility(View.VISIBLE); } } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (mBluetoothAdapter != null && mLeScanCallback != null) { mBluetoothAdapter.stopLeScan(mLeScanCallback); setProgressBarIndeterminateVisibility(false); setTitle(R.string.select_device); scanButton.setVisibility(View.VISIBLE); } } } } } }; } /** * 初始化 Android 5.0 以上蓝牙搜索结果类 */ private void initScanCallback() { mBleScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); int rssi = result.getRssi(); if (Math.abs(rssi) <= 90) { // 过滤信号小于 - 90 的设备 device = result.getDevice(); String deviceName = device.getName(); if (!StringUtils.isEmpty(deviceName) && !list.contains(device.getName() + "\n" + device.getAddress())&&(deviceName.contains("bluetooth-name01")||deviceName.contains("bluetooth-name02"))) { list.add(device.getName() + "\n" + device.getAddress()); mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); pairedListView.setAdapter(mNewDevicesArrayAdapter); mNewDevicesArrayAdapter.notifyDataSetChanged(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); if (bluetoothLeScanner != null) { bluetoothLeScanner.stopScan(mBleScanCallback); setProgressBarIndeterminateVisibility(false); setTitle(R.string.select_device); scanButton.setVisibility(View.VISIBLE); } } } } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); } }; } // The on-click listener for all devices in the ListViews private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) { String address = ((TextView) v).getText().toString(); Intent intent = new Intent(); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, address); setResult(RESULT_OK, intent); Log.i("TAG", "address=" + address); finish(); } }; private void showToas(String str) { Toast.makeText(DeviceListActivity.this, str, Toast.LENGTH_SHORT).show(); }}XML:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/title_paired_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/title_paired_devices" android:visibility="gone" android:background="#666" android:textColor="#fff" android:paddingLeft="5dp" /> <ListView android:id="@+id/paired_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:listSelector="@drawable/btn_selector" android:background="@color/white" android:stackFromBottom="true" android:dividerHeight="1dp" android:divider="@color/gray" android:layout_weight="1" /> <TextView android:id="@+id/title_new_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:visibility="gone" android:background="#666" android:textColor="#fff" android:paddingLeft="5dp" /> <ListView android:id="@+id/new_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:stackFromBottom="true" android:layout_weight="2" /> <Button android:id="@+id/button_scan" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#0B9BE9" android:textColor="@color/white" android:textSize="18sp" android:text="重新扫描" /></LinearLayout>//创建蓝牙服务public class BluetoothService extends Service implements Serializable { public static final UUID SUUIDC = UUID.fromString("0000ff00-0000-1000-8000-xxxxxxxxxxx");//服务 public static final UUID CUUIDC1 = UUID.fromString("0000ff02-0000-1000-8000-xxxxxxxxxxx");//APP从蓝牙设备获取数据使用通知通道 public static final UUID CUUIDC2 = UUID.fromString("0000ff01-0000-1000-8000-xxxxxxxxxxx");//APP向蓝牙设备写数据使用写通道 private BluetoothAdapter mBluetoothAdapter; private BluetoothManager mBluetoothManager; private BluetoothGatt mBluetoothGatt = null; public static final String ACTION_DATA_WAVAILABLE = "com.nordicsemi.nrfUART.ACTION_DATA_WAVAILABLE"; public static final String ACTION_DATA_AVAILABLE = "com.nordicsemi.nrfUART.ACTION_DATA_AVAILABLE"; public static final String ACTION_GATT_CONNECTED = "com.nordicsemi.nrfUART.ACTION_GATT_CONNECTED"; public static final String ACTION_GATT_DISCONNECTED = "com.nordicsemi.nrfUART.ACTION_GATT_DISCONNECTED"; public static final String ACTION_GATT_SERVICES_DISCOVERED = "com.nordicsemi.nrfUART.ACTION_GATT_SERVICES_DISCOVERED"; public static final String DEVICE_DOES_NOT_SUPPORT_UART = "com.nordicsemi.nrfUART.DEVICE_DOES_NOT_SUPPORT_UART"; public static final String DEVICE_DOES_NOT_SUPPORT_UARTS = "com.nordicsemi.nrfUART.DEVICE_DOES_NOT_SUPPORT_UARTS"; public static final String EXTRA_DATA = "com.nordicsemi.nrfUART.EXTRA_DATA"; private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { Log.i("TAG", "执行了:onConnectionStateChange"); if (status == BluetoothGatt.STATE_CONNECTED) {//当蓝牙设备已经连接 Log.i("TAG", "Connected to GATT server."); broadcastUpdate(ACTION_GATT_CONNECTED); mBluetoothGatt.discoverServices(); } else if (status == BluetoothGatt.STATE_DISCONNECTED) {//当设备无法连接 Log.i("TAG", "连接..."); mBluetoothGatt.discoverServices(); broadcastUpdate(ACTION_GATT_DISCONNECTED); } else { broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UARTS); } } @Override public void onServicesDiscovered(final BluetoothGatt gatt, int status) { Log.i("TAG", "执行了:onServicesDiscovered"); // 发现新服务端 if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); } else { broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UARTS); } } //数据返回的回调(此处接收BLE设备返回数据) @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { Log.i("TAG", "执行了:onCharacteristicChanged"); broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } }; private void broadcastUpdate(String paramString) { Intent localIntent = new Intent(paramString); LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); } private void broadcastUpdate(String paramString, BluetoothGattCharacteristic characteristic) { Intent localIntent = new Intent(paramString); if (CUUIDC1.toString().equals(characteristic.getUuid().toString())) { localIntent.putExtra(EXTRA_DATA, characteristic.getValue()); } LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); } private void showMessage(String msg) { Log.e("TAG", msg); } public void close() { if (this.mBluetoothGatt == null) { return; } Log.e("TAG", "mBluetoothGatt closed"); mBluetoothGatt.close(); mBluetoothGatt = null; } public boolean connect(String paramString) { if ((mBluetoothAdapter == null) || (paramString == null)) { Log.e("TAG", "没有发现设备地址,或没有初始化"); return false; } BluetoothDevice localBluetoothDevice = mBluetoothAdapter.getRemoteDevice(paramString); if (localBluetoothDevice == null) { Log.e("TAG", "设备没有找到,无法连接"); return false; } mBluetoothGatt = localBluetoothDevice.connectGatt(this, false, mGattCallback);//mGattCallback为回调接口 if (mBluetoothGatt != null) { if (mBluetoothGatt.connect()) { Log.i("TAG", "连接成功."); return true; } else { Log.e("TAG", "连接失败."); return false; } } else { Log.e("TAG", "BluetoothGatt null."); return false; } } public void disconnect() { if ((mBluetoothAdapter == null) || (mBluetoothGatt == null)) { Log.e("TAG", "BluetoothAdapter not initialized"); return; } mBluetoothGatt.disconnect(); } public boolean initialize() { if (mBluetoothManager == null) { mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); if (mBluetoothManager == null) { Log.e("TAG", "无法初始化 BluetoothManager."); return false; } } mBluetoothAdapter = this.mBluetoothManager.getAdapter(); if (mBluetoothAdapter == null) { Log.e("TAG", "无法获得 BluetoothAdapter."); return false; } return true; } private final IBinder mBinder = new LocalBinder(); @Override public IBinder onBind(Intent intent) { return mBinder; } public boolean onUnbind(Intent paramIntent) { close(); return super.onUnbind(paramIntent); } public class LocalBinder extends Binder { public LocalBinder() { } public BluetoothService getService() { return BluetoothService.this; } } public boolean setNotification() {//开启通知 boolean flag = false; if (mBluetoothGatt == null) { showMessage("service not found!"); broadcastUpdate("com.nordicsemi.nrfUART.DEVICE_DOES_NOT_SUPPORT_UARTS"); return false; } BluetoothGattService localBluetoothGattService = mBluetoothGatt.getService(SUUIDC); if (localBluetoothGattService == null) { showMessage("service not found!"); broadcastUpdate("com.nordicsemi.nrfUART.DEVICE_DOES_NOT_SUPPORT_UARTS"); return flag; } BluetoothGattCharacteristic localBluetoothGattCharacteristic = localBluetoothGattService.getCharacteristic(CUUIDC1); if (localBluetoothGattCharacteristic == null) { showMessage("charateristic not found!"); broadcastUpdate("com.nordicsemi.nrfUART.DEVICE_DOES_NOT_SUPPORT_UARTS"); return flag; } mBluetoothGatt.setCharacteristicNotification(localBluetoothGattCharacteristic, true); for (BluetoothGattDescriptor dp : localBluetoothGattCharacteristic.getDescriptors()) { if (dp != null) { dp.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); flag = mBluetoothGatt.writeDescriptor(dp); } } return flag; } public boolean iSconnet() { if (mBluetoothGatt == null) { return false; } return true; }/** * 指令 * * @return */public boolean writeDate() {//电量指令 if (mBluetoothGatt == null) { showMessage("service not found!"); return false; }}byte value[] = {(byte) 0xfa, (byte) 0xfb, 0x06, 0x00, 0x02, (byte) 0xff, (byte) 0xf7};//电量指令 BluetoothGattService localBluetoothGattService = this.mBluetoothGatt.getService(SUUIDC);if (localBluetoothGattService == null) return false; BluetoothGattCharacteristic localBluetoothGattCharacteristic = localBluetoothGattService.getCharacteristic(CUUIDC2); localBluetoothGattCharacteristic.setValue(value); boolean flag = mBluetoothGatt.writeCharacteristic(localBluetoothGattCharacteristic); return flag; }
//在主界面的MainActivity调用case R.id.bt_bluetooth://蓝牙if (mService != null && mService.writeDate() == false) { Constants.DEVICE = null; mService.close(); }//判断蓝牙设备已连接上
//如果已连上,弹出提示窗“是否要断开当前设备”
if (mService != null && mService.iSconnet() == true && mBluetoothAdapter.isEnabled() == true && deviceName != null) { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this).setTitle("已连接" + deviceName + "设备,是否要断开?") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (mBluetoothAdapter != null) { Constants.DEVICE = null; mService.close(); } } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); AlertDialog alertDialog = builder.create(); alertDialog.show(); } else { if (Build.VERSION.SDK_INT == 23) {//android 6.0 要打开定位才能搜索到设备 boolean isGps = isGpsEnable(); if (isGps == false) { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this).setTitle("该功能需要开启GPS") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (mBluetoothAdapter != null) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivityForResult(intent, 10); } } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); AlertDialog alertDialog = builder.create(); alertDialog.show(); return; } } if (mBluetoothAdapter.isEnabled() == true) {//判断蓝牙是否打开 Intent intent = new Intent(); intent.setClass(MainActivity.this, DeviceListActivity.class); startActivityForResult(intent, REQUEST_CONNECT_DEVICE_SECURE); } else { if (mService != null) { Constants.DEVICE = null; mService.close(); } Toast.makeText(MainActivity.this, "请打开蓝牙!", Toast.LENGTH_SHORT).show(); } } break;//连接蓝牙返回结果@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { String result = data.getStringExtra(BluetoothDevice.EXTRA_DEVICE); Constants.DEVICE = result.split("\\n")[1].toString().trim(); deviceName = result.split("\\n")[0].toString().trim(); Constants.DEVICE_NAME = result.split("\\n")[0].toString().trim(); BluetoothAdapter.getDefaultAdapter().getRemoteDevice(Constants.DEVICE); boolean isconnect=mService.connect(Constants.DEVICE); if(isconnect!=true){//重新连接 Log.i("TAG","重新连接..."); mService.connect(Constants.DEVICE); } }//然后开启广播接收蓝牙设备的数据private final BroadcastReceiver BluetoothStatusChangeReceiver = new BroadcastReceiver() {//广播接收器 public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(ACTION_GATT_CONNECTED)) {//连接到GATT服务端 } if (action.equals(ACTION_GATT_DISCONNECTED)) {//连接GATT服务端. } if (action.equals(ACTION_GATT_SERVICES_DISCOVERED)) {//未发现GATT服务. boolean flag = mService.setNotification();//开启通知 if (flag) { Message msg = new Message(); msg.what = BLUETOOTH_SUCCESS; mHandler.sendMessage(msg); } } if (action.equals(ACTION_DATA_AVAILABLE)) {//蓝牙设备返回的数据byte[] value = intent.getByteArrayExtra(EXTRA_DATA);} if (action.equals(DEVICE_DOES_NOT_SUPPORT_UART)) { } if (action.equals(DEVICE_DOES_NOT_SUPPORT_UARTS)) { if (progressDialog != null) { progressDialog.dismiss(); progressDialog = null; } Message msg = new Message(); msg.what = DOWN_DEFEAT; mHandler.sendMessage(msg); mService.disconnect(); } }};@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { Toast.makeText(MainActivity.this, "不支持蓝牙功能!", Toast.LENGTH_SHORT).show(); finish(); } mBluetoothAdapter.enable(); //开启 initViews(); service_init();}//注册广播private static IntentFilter makeGattUpdateIntentFilter() { final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothService.ACTION_GATT_CONNECTED); intentFilter.addAction(BluetoothService.ACTION_GATT_DISCONNECTED); intentFilter.addAction(BluetoothService.ACTION_GATT_SERVICES_DISCOVERED); intentFilter.addAction(BluetoothService.ACTION_DATA_AVAILABLE); intentFilter.addAction(BluetoothService.ACTION_DATA_WAVAILABLE); intentFilter.addAction(BluetoothService.DEVICE_DOES_NOT_SUPPORT_UART); intentFilter.addAction(DEVICE_DOES_NOT_SUPPORT_UARTS); return intentFilter;}//绑定服务 和 注册广播private void service_init() { bindService(new Intent(this, BluetoothService.class), mServiceConnection, Context.BIND_AUTO_CREATE); LocalBroadcastManager.getInstance(this).registerReceiver(BluetoothStatusChangeReceiver, makeGattUpdateIntentFilter());}public static BluetoothService mService;private ServiceConnection mServiceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName paramAnonymousComponentName, IBinder binder) { mService = ((BluetoothService.LocalBinder) binder).getService(); if (!mService.initialize()) { finish(); } } public void onServiceDisconnected(ComponentName paramAnonymousComponentName) { mService = null; }};@Overrideprotected void onDestroy() { super.onDestroy(); LocalBroadcastManager.getInstance(this).unregisterReceiver(BluetoothStatusChangeReceiver); Constants.DEVICE = null; Constants.DEVICE_NAME = null;}//再用发消息机制处理(handler)
}
阅读全文
1 0
- android 手机与蓝牙设备的通讯
- android 蓝牙通讯实现手机蓝牙的开启,并扫描附近可见的蓝牙设备
- android手机与蓝牙4.0的之间的通讯
- Android开发蓝牙与ble设备的通讯
- Android 蓝牙设备与手机之间的数据传输
- android app与蓝牙设备之间连接与通讯
- android设备终端与蓝牙模块(HC-06)的通讯编程思路
- android设备终端与蓝牙模块(HC-06)的通讯编程思路
- Android蓝牙4.0BLE与智能设备间的通讯全解析
- Android 蓝牙设备通讯的开发(配对/连接/传输数据)
- android手机蓝牙连接蓝牙设备
- 蓝牙设备与PC socket通讯
- 仿91助手的PC与android手机通讯(1) --- 检测设备插入
- 仿91助手的PC与android手机通讯(1) --- 检测设备插入
- Android 与蓝牙串口通讯
- Android BLE低功耗蓝牙开发(下) BLE客户端(中央设备)与GATT服务的通讯
- iOS 蓝牙设备与手机的距离计算
- android手机与蓝牙模块的通信
- 快照技术
- Quartz CronTrigger最完整配置说明
- C语言#error的作用
- Datatables Ajax获取多维数组数据 columns指定
- shellScript之while语句
- android 手机与蓝牙设备的通讯
- Button的EdgeInsets属性
- 基于spring的多redis数据源配置
- Aidl 基础其一 Aidl 单方向实现以及传递自定义类的对象
- RESTful SpringMVC CRUD项目(显示员工列表、rest)
- SQL利用Case When Then多条件判断
- Ubuntu16 压缩解压文件命令
- pandas read_csv 读取中文列标题文件报错
- MOS管入门----只谈应用,不谈原理