android-Low power Bluetooth (BLE)-Client (host/center device) and server (slave/peripheral)

Source: Internet
Author: User

I. Introduction to ANDROID low power Bluetooth (BLE) API
from Android 4.3 (API 18) to support the core function of Bluetooth low power, ble, ble Bluetooth protocol is the GATT protocol, BLE related classes are not many,  There are several classes in the Android.bluetooth package and the Android.bluetooth.le package: Android.bluetooth. . The bluetoothgattservice contains multiple characteristic (attribute eigenvalues), which contain a unique UUID as the identity. The bluetoothgattcharacteristic contains a single value and multiple descriptor, with a unique UUID as the identity. Bluetoothgattdescriptor describes the characteristic and contains a unique UUID as the identifier. Bluetoothgatt client related. Bluetoothgattcallback Client Connection callback. Bluetoothgattserver service-side related.  Bluetoothgattservercallback Service-side connection callback Android.bluetooth.le. . Advertisecallback the broadcast callback on the service side. Advertisedata broadcast data on the service side. Advertisesettings the broadcast settings on the service side. Bluetoothleadvertiser broadcast on the service side. Bluetoothlescanner client Scan Related (Android5.0 new). Scancallback Client Scan callback. Scanfilter client Scan filtering. Scanrecord broadcast data for client scan results. Scanresult Client scan results. Scansettings client scan Settings The BLE device is divided into two devices: the client (also called the Host/Center device/central), and the core class of the client (also called slave/peripheral/peripheral) is the core class of the Bluetoothgatt server is The core classes of Bluetoothgattserver and bluetoothleadvertiserble data are bluetoothgattcharacteristic and Bluetoothgattdescriptor
Two. Low power Bluetooth (BLE)-mobile phone as a BLE client and BLE server, read and write characteristic data

Full Source: Https://github.com/lifegh/Bluetooth

Bt_client.png

Bt_server.png

1. Bluetooth permissions
BLE privilege added bel support Check, the other is the same as the classic Bluetooth in the previous article, no longer write (1). Add Permissions in Manifest (2). In activity, set up Bluetooth//check to see if ble bluetooth if (!getpackagemanager () is supported. Hassystemfeature (Packagemanager.feature_bluetooth_le)) {    Util.toast (this, "native does not support low power Bluetooth! ");    Finish ();    return;}
2.BLE client (also called host/Center device/central) (1). Scan the BLE device (does not contain classic Bluetooth)
Note: The BLE device address is dynamic (changes every time), and the classic Bluetooth device is factory fixed! Bluetoothadapter bluetoothadapter = Bluetoothadapter.getdefaultadapter ();// The following uses the Android5.0 new scanning API, the scan returned more friendly results, such as BLE broadcast data was previously byte[] Scanrecord, and the new API to help us parse into the Scanrecord class// The old API is Bluetoothadapter.startlescan (...) Final Bluetoothlescanner Bluetoothlescanner = Bluetoothadapter.getbluetoothlescanner (); Bluetoothlescanner.startscan (Mscancallback); mhandler.postdelayed (new Runnable () {    @Override public    Void Run () {        bluetoothlescanner.stopscan (mscancallback);//stop scanning        isscanning = false;    }}, 3000);// Scan Results callbackprivate final Scancallback mscancallback = new Scancallback () {    @Override public    void Onscanresult ( int Callbacktype, scanresult result) {,        bluetoothdevice dev = result.getdevice () get BLE device information        // Result.getscanrecord () get BLE broadcast data    }};
(2). Establish a connection
Get scanning device, establish connection closeconn (); Bluetoothdevice dev = result.getdevice () Mbluetoothgatt = Dev.connectgatt (Bleclientactivity.this, False, Mbluetoothgattcallback);  Connect Bluetooth device//BLE center device The number of peripheral devices connected is limited (about 2~7), you must release the old connection resources before establishing a new connection, otherwise the connection error 133private void Closeconn () {if (Mbluetoothgatt! =)        NULL) {mbluetoothgatt.disconnect ();    Mbluetoothgatt.close ();    }}//callbackpublic bluetoothgattcallback mbluetoothgattcallback = new Bluetoothgattcallback () connected to the server. {@Override public void Onconnectionstatechange (Bluetoothgatt gatt, int status, int newstate) {Bluetoothdevice dev = gatt.ge        Tdevice (); LOG.I (TAG, String.Format ("onconnectionstatechange:%s,%s,%s,%s", Dev.getname (), dev.getaddress (), status, NewState))        ;  if (status = = Bluetoothgatt.gatt_success && newstate = = bluetoothprofile.state_connected) {isconnected            = true; Gatt.discoverservices ();            Start Service Discovery} else {isconnected = false;        Closeconn ();   }     LOGTV (String.Format (status = = 0?) (NewState = = 2?)    "Connection to [%s] succeeded": "Disconnected from [%s]"): ("Error with [%s] connection, error code:" + status), Dev)); } @Override public void onservicesdiscovered (Bluetoothgatt gatt, int status) {log.i (TAG, String.Format ("OnSe        rvicesdiscovered:%s,%s,%s ", Gatt.getdevice (). GetName (), Gatt.getdevice (). GetAddress (), status);             if (status = = bluetoothgatt.gatt_success) {//ble Service found success/traversal get all uuid of ble service services/characteristics/descriptors For (Bluetoothgattservice service:gatt.getServices ()) {StringBuilder alluuids = new Stringbu                Ilder ("uuids={ns=" + service.getuuid (). toString ()); For (bluetoothgattcharacteristic characteristic:service.getCharacteristics ()) {Alluuids.append (", nc=                    "). Append (Characteristic.getuuid ()); For (Bluetoothgattdescriptor descriptor:characteristic.getDescriptors ()) Alluuids.append (", nd=").          Append (Descriptor.getuuid ());      } alluuids.append ("}");                LOG.I (TAG, "onservicesdiscovered:" + alluuids.tostring ());            LOGTV ("Discovery service" + alluuids); }}} @Override public void Oncharacteristicread (Bluetoothgatt GATT, bluetoothgattcharacteristic character        istic, int status) {uuid UUID = Characteristic.getuuid ();        String valuestr = new String (Characteristic.getvalue ()); LOG.I (TAG, String.Format ("oncharacteristicread:%s,%s,%s,%s,%s", Gatt.getdevice (). GetName (), Gatt.getdevice ().        GetAddress (), UUID, valuestr, status);    LOGTV ("read characteristic[" + uuid + "]:n" + valuestr); } @Override public void Oncharacteristicwrite (Bluetoothgatt GATT, bluetoothgattcharacteristic characteristic, int St        atus) {uuid uuid = Characteristic.getuuid ();        String valuestr = new String (Characteristic.getvalue ()); LOG.I (TAG, String.Format ("oncharacteristicwrite:%s,%s,%s,%s,%s", Gatt.getdevice (). GetName (), Gatt.getdevice (). gEtaddress (), UUID, valuestr, status);    LOGTV ("Write characteristic[" + uuid + "]:n" + valuestr);        } @Override public void oncharacteristicchanged (Bluetoothgatt GATT, bluetoothgattcharacteristic characteristic) {        UUID uuid = Characteristic.getuuid ();        String valuestr = new String (Characteristic.getvalue ()); LOG.I (TAG, String.Format ("oncharacteristicchanged:%s,%s,%s,%s", Gatt.getdevice (). GetName (), Gatt.getdevice ().        GetAddress (), UUID, valuestr));    LOGTV ("Notification characteristic[" + UUID + "]:n" + valuestr);        } @Override public void Ondescriptorread (Bluetoothgatt GATT, bluetoothgattdescriptor descriptor, int status) {        UUID uuid = Descriptor.getuuid ();        String valuestr = arrays.tostring (Descriptor.getvalue ()); LOG.I (TAG, String.Format ("ondescriptorread:%s,%s,%s,%s,%s", Gatt.getdevice (). GetName (), Gatt.getdevice ().        GetAddress (), UUID, valuestr, status);    LOGTV ("read descriptor[" + uuid + "]:n" + valuestr); } @Override PubLIC void Ondescriptorwrite (Bluetoothgatt GATT, bluetoothgattdescriptor descriptor, int status) {uuid UUID = Descri        Ptor.getuuid ();        String valuestr = arrays.tostring (Descriptor.getvalue ()); LOG.I (TAG, String.Format ("ondescriptorwrite:%s,%s,%s,%s,%s", Gatt.getdevice (). GetName (), Gatt.getdevice ().        GetAddress (), UUID, valuestr, status);    LOGTV ("Write descriptor[" + uuid + "]:n" + valuestr); }};
(3). Transmitting data (read-write characteristic and descriptor)
Note: 1. Each read and write data up to 20 bytes, if exceeded, can only be divided into 2. Continuous frequent read and write data is easy to fail, read and write operation interval is better than 200ms, or wait for the last callback to complete the next read and write operation! Read data success will callback->oncharacteristicchanged () public void read (view view) {Bluetoothgattservice service = Getgattservice (B    Leserveractivity.uuid_service); if (service! = null) {bluetoothgattcharacteristic characteristic = service.getcharacteristic (bleserveractivity.uui    d_char_read_notify);//The characteristic mbluetoothgatt.readcharacteristic (characteristic) can be obtained by UUID; }}//Write Data success will callback->oncharacteristicwrite () public void write (view view) {Bluetoothgattservice service = Getgattservice (    Bleserveractivity.uuid_service);        if (service = null) {String text = Mwriteet.gettext (). toString (); Bluetoothgattcharacteristic characteristic = service.getcharacteristic (bleserveractivity.uuid_char_write);// Obtain a writable characteristic characteristic.setvalue (Text.getbytes ()) from the UUID;    Up to 20 bytes mbluetoothgatt.writecharacteristic (characteristic) in a single time; }}//access to GATT services private BluetooThgattservice getgattservice (uuid uuid) {Bluetoothgattservice service = Mbluetoothgatt.getservice (UUID);    if (service = = null) Util.toast (this, "services uuid= not found" + uuid); return service;}
(4). Set notification, real-time monitoring characteristic changes
Characteristic changes will callback->oncharacteristicchanged () Bluetoothgattservice service = Getgattservice ( Bleserveractivity.uuid_service); if (SERVICE! = null) {    //Set characteristic notification    bluetoothgattcharacteristic characteristic = Service.getcharacteristic (bleserveractivity.uuid_char_read_notify);//The UUID gets the characteristic that can be notified    mbluetoothgatt.setcharacteristicnotification (characteristic, true);    Write a notification switch to the characteristic descriptor property to enable the bluetooth® device to proactively send data to the phone    bluetoothgattdescriptor descriptor = Characteristic.getdescriptor (bleserveractivity.uuid_desc_notity);    Descriptor.setvalue (Bluetoothgattdescriptor.enable_indication_value);//similar to notifications, but the server does not actively send data, only instructs the client to read the data    Descriptor.setvalue (bluetoothgattdescriptor.enable_notification_value);    Mbluetoothgatt.writedescriptor (descriptor);}
3.BLE Service End (also called slave/peripheral/peripheral)
public static final UUID Uuid_service = uuid.fromstring ("10000000-0000-0000-0000-000000000000"); Custom Uuidpublic static final UUID uuid_char_read_notify = uuid.fromstring ("11000000-0000-0000-0000-000000000000"); public static final UUID uuid_desc_notity = uuid.fromstring ("11100000-0000-0000-0000-000000000000");p ublic static Final UUID uuid_char_write = uuid.fromstring ("12000000-0000-0000-0000-000000000000");p rivate Bluetoothleadvertiser Mbluetoothleadvertiser; BLE broadcast private bluetoothgattserver mbluetoothgattserver;    ble server @overrideprotected void onCreate (Bundle savedinstancestate) {...    Bluetoothmanager Bluetoothmanager = (bluetoothmanager) getsystemservice (Context.bluetooth_service);    Bluetoothadapter bluetoothadapter = Bluetoothmanager.getadapter ();    Bluetoothadapter bluetoothadapter = Bluetoothadapter.getdefaultadapter (); ============ start ble bluetooth broadcast (AD) =================================================================================// Broadcast settings (required) AdvertisesettIngs settings = new Advertisesettings.builder (). Setadvertisemode (Advertisesettings.advertise_mode_low_latency) Broadcast mode: Low power, balanced, low latency. Settxpowerlevel (Advertisesettings.advertise_tx_power_high)//Transmit power level: very low, low, medium, high.    Setconnectable (TRUE)//can be connected, broadcast is divided into both connected and non-connected broadcasts. Build (); Broadcast data (must, broadcast start will be sent) advertisedata Advertisedata = new Advertisedata.builder (). Setincludedevicename (True)// Contains the Bluetooth name. Setincludetxpowerlevel (TRUE)//contains the transmit power level. Addmanufacturerdata (1, New byte[]{23, 33})//Device Vendor data    , Custom. Build ();  Scan response data (optional, sent when client scans) Advertisedata Scanresponse = new Advertisedata.builder (). Addmanufacturerdata (2, new BYTE[]{66, 66})//device manufacturer data, custom. Addserviceuuid (New Parceluuid (Uuid_service))//service UUID//. Addservicedata    (New Parceluuid (Uuid_service), New byte[]{2})//service data, Custom. Build ();    Mbluetoothleadvertiser = Bluetoothadapter.getbluetoothleadvertiser (); MbluetoothleadveRtiser.startadvertising (Settings, Advertisedata, Scanresponse, Madvertisecallback);    Note: You must turn on the connected BLE broadcast, and other devices will be able to discover and connect to the BLE server!    ============= start the BLE bluetooth service side =====================================================================================    Bluetoothgattservice service = new Bluetoothgattservice (Uuid_service, bluetoothgattservice.service_type_primary); Add a readable + notification characteristic bluetoothgattcharacteristic characteristicread = new Bluetoothgattcharacteristic (UUID_CHAR_ Read_notify, Bluetoothgattcharacteristic.property_read |    Bluetoothgattcharacteristic.property_notify, Bluetoothgattcharacteristic.permission_read); Characteristicread.adddescriptor (New Bluetoothgattdescriptor (Uuid_desc_notity,    Bluetoothgattcharacteristic.permission_write));    Service.addcharacteristic (Characteristicread); Add writable characteristic bluetoothgattcharacteristic characteristicwrite = new Bluetoothgattcharacteristic (UUID_CHAR_ WRITE, Bluetoothgattcharacteristic.property_write,Bluetoothgattcharacteristic.permission_write);    Service.addcharacteristic (Characteristicwrite); if (Bluetoothmanager! = null) Mbluetoothgattserver = Bluetoothmanager.opengattserver (This, mbluetoothgattservercall    back); Mbluetoothgattserver.addservice (service);} BLE broadcast callbackprivate advertisecallback madvertisecallback = new Advertisecallback () {@Override public void Onsta    Rtsuccess (advertisesettings settingsineffect) {LOGTV ("BLE broadcast turned on successfully");    } @Override public void onstartfailure (int errorCode) {LOGTV ("BLE broadcast on failure, error code:" + ErrorCode); }};//ble server callbackprivate bluetoothgattservercallback mbluetoothgattservercallback = new Bluetoothgattservercallback () {@Override public void Onconnectionstatechange (Bluetoothdevice device, int. status, in T newstate) {log.i (TAG, String.Format ("onconnectionstatechange:%s,%s,%s,%s", Device.getname (), device.getAddress ()        , status, NewState)); LOGTV (String.Format (status = = 0?) (NewState = = 2?) "connection to [%s] successfully ":" "Disconnected from [%s]"): ("Connection error with [%s], error code:" + status), device)); } @Override public void onserviceadded (int status, Bluetoothgattservice service) {log.i (TAG, String.Format ("        onserviceadded:%s,%s ", Status, Service.getuuid ())); LOGTV (String.Format (status = = 0?)    "Add service [%s] succeeded": "Add service [%s] failed with error code:" + Status, Service.getuuid ())); } @Override public void Oncharacteristicreadrequest (bluetoothdevice device, int requestid, int offset, Bluetoothgatt Characteristic characteristic) {log.i (TAG, String.Format ("oncharacteristicreadrequest:%s,%s,%s,%s,%s", Device.getN        Ame (), device.getaddress (), RequestID, offset, characteristic.getuuid ())); String response = "Char_" + (int) (Math.random () * 100); Analog data Mbluetoothgattserver.sendresponse (device, RequestID, bluetoothgatt.gatt_success, offset, response.getbytes ()    );//Response Client LOGTV ("client read characteristic[" + characteristic.getuuid () + "]:n" + response); } @Override public void OncharacteristiCwriterequest (bluetoothdevice device, int requestid, bluetoothgattcharacteristic characteristic, Boolean  Preparedwrite, Boolean responseneeded, int offset, byte[] requestbytes) {//Get the data sent by the client String Requeststr =        New String (requestbytes); LOG.I (TAG, String.Format ("oncharacteristicwriterequest:%s,%s,%s,%s,%s,%s,%s,%s", Device.getname (), Device.getaddress (), RequestID, Characteristic.getuuid (), Preparedwrite, responseneeded, offset, requestStr        )); Mbluetoothgattserver.sendresponse (device, RequestID, bluetoothgatt.gatt_success, offset, requestbytes);//Response client Log    Tv ("Client write characteristic[" + characteristic.getuuid () + "]:n" + requeststr); } @Override public void Ondescriptorreadrequest (bluetoothdevice device, int requestid, int offset, BLUETOOTHGATTDESC Riptor descriptor) {log.i (TAG, String.Format ("ondescriptorreadrequest:%s,%s,%s,%s,%s", Device.getname (), device.ge        Taddress (), RequestID, offset, descriptor.getuuid ()));String response = "DESC_" + (int) (Math.random () * 100); Analog data Mbluetoothgattserver.sendresponse (device, RequestID, bluetoothgatt.gatt_success, offset, response.getbytes () );    Response Client LOGTV ("client read descriptor[" + descriptor.getuuid () + "]:n" + response); } @Override public void Ondescriptorwriterequest (final bluetoothdevice device, int RequestID, Bluetoothgattdescripto R Descriptor, Boolean Preparedwrite, Boolean responseneeded, int offset, byte[] value) {//Get data sent by the client Stri        ng valuestr = arrays.tostring (value); LOG.I (TAG, String.Format ("ondescriptorwriterequest:%s,%s,%s,%s,%s,%s,%s,%s", Device.getname (), Device.getAddress (        ), RequestID, Descriptor.getuuid (), Preparedwrite, responseneeded, offset, valuestr)); Mbluetoothgattserver.sendresponse (device, RequestID, bluetoothgatt.gatt_success, offset, value);//Response Client LOGTV ("Client        Write descriptor["+ descriptor.getuuid () +"]:n "+ valuestr);   Simple analog notification client characteristic changes     if (arrays.tostring (Bluetoothgattdescriptor.enable_notification_value). Equals (VALUESTR)) {//whether to turn on notification final            Bluetoothgattcharacteristic characteristic = descriptor.getcharacteristic ();  New Thread (New Runnable () {@Override public void run () {for (int i = 0; I < 5;                        i++) {systemclock.sleep (3000); String response = "Char_" + (int) (Math.random () * 100);                        Analog Data Characteristic.setvalue (response);                        Mbluetoothgattserver.notifycharacteristicchanged (device, characteristic, false);                    LOGTV ("Notify Client change characteristic[" + characteristic.getuuid () + "]:n" + response);        }}). Start (); }} @Override public void Onexecutewrite (bluetoothdevice device, int RequestID, Boolean execute) {log.i (T AG, String.Format ("onexecutewrite:%s,%s,%s,%s", Device.getnamE (), device.getaddress (), RequestID, execute)); } @Override public void Onnotificationsent (Bluetoothdevice device, int. status) {LOG.I (TAG, String.Format ("on    notificationsent:%s,%s,%s ", Device.getname (), device.getaddress (), status)); } @Override public void onmtuchanged (Bluetoothdevice device, int MTU) {log.i (TAG, String.Format ("Onmtuchange    d:%s,%s,%s ", Device.getname (), device.getaddress (), MTU)); }};

Pinterest: Https://www.jianshu.com/p/8ac31a5070d4

csdn:80643906

GitHub Blog: http://lioil.win/2018/06/10/Android-BLE.html

Coding Blog: http://c.lioil.win/2018/06/10/Android-BLE.html

android-Low power Bluetooth (BLE)-Client (host/center device) and server (slave/peripheral)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.