android蓝牙BLE串口开发

1.首先申请相关权限。在manifest.xml

    
    
    
    
    
       .....
    

2.声明蓝牙适配器,申请打开蓝牙

        private  BluetoothAdapter mBluetoothAdapter;

        // 判断手机硬件支持蓝牙
        if (!getPackageManager().hasSystemFeature( PackageManager.FEATURE_BLUETOOTH_LE))
        {
            Toast.makeText(this, "手机不支持BLE", Toast.LENGTH_SHORT).show();
            finish();//退出
        }
        
        // 获取手机本地的蓝牙适配器
        final BluetoothManager bluetoothManager = 
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        // 打开蓝牙权限
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())
        {
            //弹出对话框,请求打开蓝牙
            startActivityForResult(new Intent(  BluetoothAdapter.ACTION_REQUEST_ENABLE), REQUEST_ENABLE_BT);
        }

3.扫描蓝牙设备

    mBluetoothAdapter.startLeScan(mLeScanCallback);//开始扫描
    mBluetoothAdapter.stopLeScan(mLeScanCallback);//停止扫描

    /**
     * 蓝牙扫描回调函数 回调蓝牙BluetoothDevice,可以获取name MAC rsss 广播等信息
     *
     * **/
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback()
    {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord)
        {
            // TODO 
            runOnUiThread(new Runnable()
            {
                @Override
                public void run()
                {
                    /* 这里将扫描到设备的信息输出到相应界面显示 */
                }
            });
        }
    };

必须注意的是,android5.0以上,使用BluetoothLeScanner进行扫描,以上函数已经不推荐了。

private BluetoothLeScanner bluetoothLeScanner;

bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); 
bluetoothLeScanner.startScan(scanCallback);

private ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult results) {
            super.onScanResult(callbackType, results);
            BluetoothDevice device = results.getDevice();
            //BluetoothDevice 包含了蓝牙设备的各种信息,比如名字,MAC,等等
            //可在此添加扫描的设备到显示界面      
	   }
};
//扫描需要一些时间,想停止可使用一下函数
bluetoothLeScanner.stopScan(scanCallback);

4.连接蓝牙

上面手机扫描到其他蓝牙设备(GAP协议),接下来就要建立连接,通讯(GATT协议)。

//蓝牙service,负责后台的蓝牙服务
private static BluetoothLeService mBluetoothLeService;
//蓝牙特征
private ArrayList> mGattCharacteristics = 
new ArrayList>();

蓝牙是通过Characteristic进行数据交互的,详细可百度相关知识点。

绑定服务

    /* 启动蓝牙service */
    Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);

	/* BluetoothLeService绑定的回调函数 */
    private final ServiceConnection mServiceConnection = new ServiceConnection()
	{
		@Override
		public void onServiceConnected(ComponentName componentName,
									   IBinder service)
		{
			mBluetoothLeService = ((BluetoothLeService.LocalBinder) service)
					.getService();
			if (!mBluetoothLeService.initialize())
			{
				Log.e(TAG, "Unable to initialize Bluetooth");
				finish();
			}
			// 根据蓝牙地址,连接设备
			mBluetoothLeService.connect(mDeviceAddress);
		}

		@Override
		public void onServiceDisconnected(ComponentName componentName)
		{
			mBluetoothLeService = null;
		}

	};
5.处理蓝牙服务
     /**
	 * @Title: displayGattServices
	 * @Description: 处理蓝牙服务
	 * @param
	 * @return void
	 * @throws
	 */
	private void displayGattServices(List gattServices)
	{
		if (gattServices == null)
			return;
		String uuid = null;
		String unknownServiceString = "unknown_service";
		String unknownCharaString = "unknown_characteristic";
		// 服务数据,可扩展下拉列表的第一级数据
		ArrayList> gattServiceData = 
new ArrayList>();
		// 特征数据(隶属于某一级服务下面的特征值集合)
		ArrayList>> gattCharacteristicData = 
new ArrayList>>();
		// 部分层次,所有特征值集合
		mGattCharacteristics = new ArrayList>();
		// Loops through available GATT Services.
		for (BluetoothGattService gattService : gattServices)
		{
			// 获取服务列表
			HashMap currentServiceData = new HashMap();
			uuid = gattService.getUuid().toString();

			// 查表,根据该uuid获取对应的服务名称。SampleGattAttributes这个表需要自定义。
			gattServiceData.add(currentServiceData);
			System.out.println("Service uuid:" + uuid);
			ArrayList> gattCharacteristicGroupData = 
new ArrayList>();
			// 从当前循环所指向的服务中读取特征值列表
			List gattCharacteristics = gattService
					.getCharacteristics();
			ArrayList charas = 
new ArrayList();
			// Loops through available Characteristics.
			// 对于当前循环所指向的服务中的每一个特征值
			for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics)
			{
				charas.add(gattCharacteristic);
				HashMap currentCharaData = new HashMap();
				uuid = gattCharacteristic.getUuid().toString();

				if (gattCharacteristic.getUuid().toString()
						.equals(HEART_RATE_MEASUREMENT))
				{
					mhandler.postDelayed(new Runnable()
					{
						@Override
						public void run()
						{
							// TODO Auto-generated method stub
							mBluetoothLeService.readCharacteristic(gattCharacteristic);
						}
					}, 200);

					mBluetoothLeService.setCharacteristicNotification(
							gattCharacteristic, true);
					target_chara = gattCharacteristic;
				}
				List descriptors = gattCharacteristic
						.getDescriptors();
				for (BluetoothGattDescriptor descriptor : descriptors)
				{
					System.out.println("---descriptor UUID:"
							+ descriptor.getUuid());
					// 获取特征值的描述
					mBluetoothLeService.getCharacteristicDescriptor(descriptor);
				}
				gattCharacteristicGroupData.add(currentCharaData);
			}
			// 按先后顺序,分层次放入特征值集合中,只有特征值
			mGattCharacteristics.add(charas);
			// 构件第二级扩展列表(服务下面的特征值)
			gattCharacteristicData.add(gattCharacteristicGroupData);
		}
	}

当需要发送数据时,注意一次发送的数据是有限制的。

private static BluetoothGattCharacteristic cdata= null;

cdata.setValue(str);//str为需要发送的数据
//调用蓝牙服务的写特征值方法实现发送数据
mBluetoothLeService.writeCharacteristic(cdata);

最后定义一个广播接收器专门负责接收处理蓝牙服务。

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        //...
    }
}

6.实际测试

使用蓝牙串口模块与电脑连接,打开PC串口助手。测试

android蓝牙BLE串口开发_第1张图片android蓝牙BLE串口开发_第2张图片android蓝牙BLE串口开发_第3张图片

电脑端可以正常接收。

android蓝牙BLE串口开发_第4张图片

这个电脑端的串口软件也是我用C#编写的。

我本来使用XCOM作为串口接收软件,不过XCOM接收是按照GB2312编码接收。

你可能感兴趣的:(android,无线通信,蓝牙BLE,蓝牙串口)