android Bluetooth BLE serial port development

1. First apply for relevant authority. In manifest.xml

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-feature android:name="android.bluetooth_le" android:required="true"/>
    <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <application>
       .....
    </application>

2. Declare Bluetooth adapter and apply for Bluetooth

        private  BluetoothAdapter mBluetoothAdapter;

        // Judge whether the mobile hardware supports Bluetooth
        if (!getPackageManager().hasSystemFeature( PackageManager.FEATURE_BLUETOOTH_LE))
        {
            Toast.makeText(this, "Phone does not support BLE", Toast.LENGTH_SHORT).show();
            finish();//Sign out
        }
        
        // Get local Bluetooth adapter of mobile phone
        final BluetoothManager bluetoothManager = 
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        // Open Bluetooth permission
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())
        {
            //Pop up dialog box, request to open Bluetooth
            startActivityForResult(new Intent(  BluetoothAdapter.ACTION_REQUEST_ENABLE), REQUEST_ENABLE_BT);
        }

3. Scan Bluetooth devices

    mBluetoothAdapter.startLeScan(mLeScanCallback);//Start scanning
    mBluetoothAdapter.stopLeScan(mLeScanCallback);//Stop scanning

    /**
     * The Bluetooth scan callback function calls back to Bluetooth Bluetooth device to obtain name MAC rsss broadcast and other information
     *
     * **/
    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()
                {
                    /* Here, the information scanned to the device is output to the corresponding interface for display */
                }
            });
        }
    };

It must be noted that above Android 5.0, using Bluetooth lescanner for scanning, the above functions are not recommended.

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();
            //Bluetooth device contains various information of Bluetooth device, such as name, MAC, etc
            //You can add scanned devices to the display interface here      
	   }
};
//Scanning takes some time. To stop scanning, you can use the following functions
bluetoothLeScanner.stopScan(scanCallback);

4. connect Bluetooth

The above mobile phones scan to other Bluetooth devices (GAP protocol), and then establish the connection and communication (GATT protocol).

//Bluetooth service, responsible for the background Bluetooth service
private static BluetoothLeService mBluetoothLeService;
//Bluetooth features
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = 
new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

Bluetooth carries out data interaction through Characteristic, and Baidu related knowledge points are available in detail.

Binding service

    /* Start Bluetooth service */
    Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);

	/* BluetoothLeService Bound callback function */
    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();
			}
			// Connect the device according to the Bluetooth address
			mBluetoothLeService.connect(mDeviceAddress);
		}

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

	};
5. Handle Bluetooth service
     /**
	 * @Title: displayGattServices
	 * @Description: Handle Bluetooth services
	 * @param
	 * @return void
	 * @throws
	 */
	private void displayGattServices(List<BluetoothGattService> gattServices)
	{
		if (gattServices == null)
			return;
		String uuid = null;
		String unknownServiceString = "unknown_service";
		String unknownCharaString = "unknown_characteristic";
		// Service data, first level data of extensible drop-down list
		ArrayList<HashMap<String, String>> gattServiceData = 
new ArrayList<HashMap<String, String>>();
		// Characteristic data (belonging to the set of characteristic values under a certain level of service)
		ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = 
new ArrayList<ArrayList<HashMap<String, String>>>();
		// Partial hierarchy, all eigenvalue sets
		mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
		// Loops through available GATT Services.
		for (BluetoothGattService gattService : gattServices)
		{
			// Get service list
			HashMap<String, String> currentServiceData = new HashMap<String, String>();
			uuid = gattService.getUuid().toString();

			// Look up the table and get the corresponding service name according to the uuid. SampleGattAttributes this table needs to be customized.
			gattServiceData.add(currentServiceData);
			System.out.println("Service uuid:" + uuid);
			ArrayList<HashMap<String, String>> gattCharacteristicGroupData = 
new ArrayList<HashMap<String, String>>();
			// Read the list of eigenvalues from the service pointed to by the current loop
			List<BluetoothGattCharacteristic> gattCharacteristics = gattService
					.getCharacteristics();
			ArrayList<BluetoothGattCharacteristic> charas = 
new ArrayList<BluetoothGattCharacteristic>();
			// Loops through available Characteristics.
			// For each eigenvalue in the service that the current loop points to
			for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics)
			{
				charas.add(gattCharacteristic);
				HashMap<String, String> currentCharaData = new HashMap<String, String>();
				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<BluetoothGattDescriptor> descriptors = gattCharacteristic
						.getDescriptors();
				for (BluetoothGattDescriptor descriptor : descriptors)
				{
					System.out.println("---descriptor UUID:"
							+ descriptor.getUuid());
					// Get the description of the eigenvalue
					mBluetoothLeService.getCharacteristicDescriptor(descriptor);
				}
				gattCharacteristicGroupData.add(currentCharaData);
			}
			// In order of priority, it is put into the set of eigenvalues hierarchically, with only eigenvalues
			mGattCharacteristics.add(charas);
			// Second level extension list of components (eigenvalues under services)
			gattCharacteristicData.add(gattCharacteristicGroupData);
		}
	}

When you need to send data, note that there is a limit to the data that can be sent at one time.

private static BluetoothGattCharacteristic cdata= null;

cdata.setValue(str);//str is the data to be sent
//Calling the write eigenvalue method of Bluetooth service to send data
mBluetoothLeService.writeCharacteristic(cdata);

Finally, a broadcast receiver is defined to receive and process Bluetooth services.

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

6. Actual test

Use Bluetooth serial port module to connect with computer and open PC serial port assistant. test

The computer can receive normally.

The serial port software of this computer is also written by me in C.

I used to use XCOM as the serial port receiving software, but XCOM received according to GB2312 code.

Keywords: Android Mobile Mac xml

Added by Ohio Guy on Sat, 01 Feb 2020 05:32:42 +0200