Bluetooth analysis, bluetooth
This article analyzes the usage of android Bluetooth, including enabling and disabling Bluetooth, setting visibility, starting to cancel discovery, pairing, active connection, anti-connection, broadcast, and so on.
1. Demo
Public class MainActivity extends Activity {private static final String TAG = MainActivity. class. getSimpleName (); private descrithadapter; private static final int ENABLE_BLUETOOTH = 0x0; private static final int DISCOVER_REQUEST = 0x1; private List <effecthdevice> deviceList = new ArrayList <effecthdevice> (); ArrayAdapter <String> arrayAdapter; effecthdevice implements thdevice; private Effecthsocket transferSocket;/** instantiate InputStream and OutputStream */private OutputStream OS; private InputStream is; UUID uuid; EditText inbox; ListView after receiving the broadcast established by the connection; byte [] tmpBytes = new byte [32]; public int count = 0; @ Overrideprotected void onCreate (Bundle savedInstanceState) {Log. d (TAG, "onCreate"); super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); inbox = (EditText) findVie WById (R. id. inbox); listView = (ListView) findViewById (R. id. listView); listView. setOnItemClickListener (mOnItemClickListener); arrayAdapter = new ArrayAdapter <String> (MainActivity. this, android. r. layout. simple_list_item_1, new ArrayList <String> (); listView. setAdapter (arrayAdapter); // UUID = uuid used for rescue by Bian Que. fromString ("20171101-0000-1000-8000-00805f9b34fb"); then thadapter = ~thadapter. getDefaultA Dapter (); initBluetooth ();} private void initBluetooth () {IntentFilter filter = new IntentFilter (); filter. addAction (descrithadapter. ACTION_DISCOVERY_STARTED); filter. addAction (descrithadapter. ACTION_DISCOVERY_FINISHED); filter. addAction (descrithdevice. ACTION_FOUND); filter. addAction (descrithdevice. ACTION_ACL_CONNECTED); filter. addAction (descrithdevice. ACTION_ACL_DISCONNECTED); registerReceiver (mRecei Ver, filter); if (! Descrithadapter. isEnabled () {startActivityForResult (new Intent (effecthadapter. ACTION_REQUEST_ENABLE), ENABLE_BLUETOOTH);} else {startServerSocket () ;}@overrideprotected void onDestroy () {Log. d (TAG, "onDestroy"); super. onDestroy (); unregisterReceiver (mReceiver); resetSocket (); isRunning = false;}/** receive read data, and then send the command */private void receiveData (byte [] data, int len) {System. arraycopy (data, 0, tmpBytes, count, Len); count + = len; if (count = 5 & arrayEquals (tmpBytes, "READY ". getBytes (), count) {// 5 READYprint (tmpBytes, count); count = 0; try {SystemClock. sleep (500); OS. write ("VER00 ". getBytes (); // get version data} catch (IOException e) {e. printStackTrace () ;}} else if (count = 15 & tmpBytes [0] = 'O' & checkSum (tmpBytes, 3, 14 )) {// 1-9-5 receive version dataprint (tmpBytes, count); count = 0; try {System Clock. sleep (500); OS. write ("GAT00 ". getBytes (); // get automatic transmission} catch (IOException e) {e. printStackTrace () ;}} else if (count = 5 & tmpBytes [0] = 'O' & checkSum (tmpBytes, 3, 4 )) {// automatic transmissionbyte set = tmpBytes [3]; print (tmpBytes, count); count = 0; try {if (set = 0x00) {// 0: not; 1: yes. If automatic transmission is not set, set SystemClock first. sleep (500); OS. write (new byte [] {'s ', 'A', 't',' \ 0', 0x11, 0x11 }); // Set automatic transmissionSystemClock. sleep (500);} OS. write ("GPD00 ". getBytes (); // get profile data} catch (IOException e) {e. printStackTrace () ;}} else if (count = 14 & tmpBytes [0] = 'O' & checkSum (tmpBytes, 3, 13 )) {// 1-8-5 receive profile dataprint (tmpBytes, count); count = 0; try {SystemClock. sleep (500); OS. write ("GDN00 ". getBytes (); // send 'get data number' command} catch (IOException e) {E. printStackTrace () ;}} else if (count = 8 & tmpBytes [0] = 'O' & checkSum (tmpBytes, 3, 7 )) {// 1-7 receive data numberprint (tmpBytes, count); count = 0; try {SystemClock. sleep (500); OS. write (new byte [] {'G', 'M', 'D', '\ 0', 0, 0 }); // send 'get measurement data' command} catch (IOException e) {e. printStackTrace () ;}} else if (count = 18 & tmpBytes [0] = 'O' & checkSum (tmpBytes, 3, 17 )) {// 1-9-8 Receive measurement dataprint (tmpBytes, count); count = 0; try {SystemClock. sleep (500); OS. write (new byte [] {'T', 'O', 'k', (byte) 0xff, (byte) 0xff});} catch (IOException e) {e. printStackTrace () ;}} else if (count = 2 & arrayEquals ("OK ". getBytes (), tmpBytes, count) {// TOK will receive OKprint (tmpBytes, count); count = 0 ;}} /** verify that the received data is correct */private boolean checkSum (byte [] data, int start, int end) {byte check = 0; for (in T I = start; I <= end; I ++) {check ^ = data [I];} if (check = 0) {return true;} return false ;} /** determine whether the two byte arrays are the same * <li> compare the values from 0 to len in two arrays */private boolean arrayEquals (byte [] one, byte [] another, int len) {if (one = null | another = null) {return false;} if (len <0 | len> one. length | len> another. length) {return false ;}for (int I = 0; I <len; I ++) {if (one [I]! = Another [I]) {return false;} return true;} Handler handler = new Handler (); private void print (byte [] bytes, int len) {final StringBuilder sb = new StringBuilder (); for (int I = 0; I <len; I ++) {sb. append (bytes [I]). append (",");} handler. post (new Runnable () {@ Overridepublic void run () {inbox. append (sb + "\ n") ;}}) ;} private boolean listening; @ Overrideprotected void onActivityResult (int requestCode, int resultCode, Intent data) {super. onActivityResult (requestCode, resultCode, data); if (requestCode = ENABLE_BLUETOOTH) {if (resultCode = RESULT_ OK) {Toast. makeText (this, "Bluetooth is enabled", Toast. LENGTH_SHORT ). show () ;}} else if (requestCode = DISCOVER_REQUEST) {if (resultCode = RESULT_ OK) {Toast. makeText (this, "Bluetooth is discoverable", Toast. LENGTH_SHORT ). show () ;}} public void onClick (View v) {switch (v. getId () {Case R. id. discoverable: // visible to all nearby devices. Use anti-connection. // If Bluetooth is unavailable, the system prompts to enable Bluetooth startActivityForResult (new Intent (effecthadapter. ACTION_REQUEST_DISCOVERABLE), DISCOVER_REQUEST); break; case R. id. discover: if (! Descrithadapter. isEnabled () {startActivityForResult (new Intent (descrithadapter. ACTION_REQUEST_ENABLE), ENABLE_BLUETOOTH);} else if (! Descrithadapter. isDiscovering () {// inquiry scan of 12 s, followed by a page scan of each new devicebluw.thadapter. startDiscovery ();} break; case R. id. accept: startServerSocket (); break; case R. id. clearEdit: inbox. setText (""); arrayAdapter. clear (); deviceList. clear () ;}} boolean isRunning = true;/*** the current device acts as the server for anti-connection, listening for connection requests * single-thread loop listening connection */private void startServerSocket () {Toast. makeText (this, "anti-connection process startup", Toast. L ENGTH_SHORT ). show (); try {final cmdthserversocket server = cmdthadapter. listenUsingInsecureRfcommWithServiceRecord ("effecthserver", uuid); new Thread (new Runnable () {@ Overridepublic void run () {while (isRunning) {try {transferSocket = server. accept (); try {is = transferSocket. getInputStream (); OS = transferSocket. getOutputStream ();} catch (IOException e) {e. printStackTrace ();} if (mReadThread = n Ull |! MReadThread. isAlive () {mReadThread = new ReadThread (); mReadThread. start () ;}} catch (IOException e) {e. printStackTrace ();}}}}). start ();} catch (IOException e) {e. printStackTrace () ;}/ ** actively connect to the device */private OnItemClickListener mOnItemClickListener = new OnItemClickListener () {@ Overridepublic void onItemClick (AdapterView <?> Parent, View view, int position, long id) {try {descrithdevice = deviceList. get (position); Log. d (TAG, "before bond-" + descrithdevice. getBondState (); if (then thdevice. getBondState () = descrithdevice. BOND_BONDING) {Toast. makeText (MainActivity. this, "pairing... ", Toast. LENGTH_SHORT ). show (); return;} if (descrithdevice. getBondState () = descrithdevice. BOND_NONE) {// boolean retValue = bluet OothDevice. createBond (); // pairing orMethod = descrithdevice. class. getMethod ("createBond"); boolean retValue = (Boolean) method. invoke (effecthdevice); if (retValue) {// true indicates that the pairing process starts new ConnectThread (true ). start (); return ;}} new ConnectThread (false ). start ();} catch (Exception e) {e. printStackTrace () ;}}; private class ConnectThread extends Thread {boolean isBonding; public ConnectThread (boolean isBonding) {This. isBonding = isBonding;} @ Overridepublic void run () {super. run (); if (isBonding) {long start = SystemClock. elapsedRealtime (); while (descrithdevice. getBondState ()! = Effecthdevice. BOND_BONDED) {// the pairing process is approximately 10sSystemClock. sleep (50);} Log. d (TAG, "pairing successful-" + (SystemClock. elapsedRealtime ()-start) + "ms");} try {transferSocket = effecthdevice. createInsecureRfcommSocketToServiceRecord (uuid); long start = SystemClock. elapsedRealtime (); transferSocket. connect (); // connect to Log. d (TAG, "after connect-" + (SystemClock. elapsedRealtime ()-start) + "ms"); is = transferSocket. getInputStream (); OS = t RansferSocket. getOutputStream (); if (mReadThread = null |! MReadThread. isAlive () {mReadThread = new ReadThread (); mReadThread. start () ;}} catch (Exception e) {e. printStackTrace () ;}}/ *** close InputStream, OutputStream, javasthsocket * in Activity. onDestroy call */private void resetSocket () {Log. d (TAG, "resetSocket"); listening = false; try {if (is! = Null) is. close ();} catch (IOException e1) {e1.printStackTrace ();} try {if (OS! = Null) OS. close ();} catch (IOException e1) {e1.printStackTrace ();} try {if (transferSocket! = Null) transferSocket. close ();} catch (IOException e) {e. printStackTrace () ;}} private BroadcastReceiver mReceiver = new BroadcastReceiver () {@ Overridepublic void onReceive (Context context, Intent intent) {if (descrithadapter. ACTION_DISCOVERY_STARTED.equals (intent. getAction () {Toast. makeText (MainActivity. this, "Start of discovery", Toast. LENGTH_SHORT ). show (); arrayAdapter. clear (); deviceList. clear ();} else if (Bluetoo ThAdapter. ACTION_DISCOVERY_FINISHED.equals (intent. getAction () {Toast. makeText (MainActivity. this, "Discovery completed", Toast. LENGTH_SHORT ). show ();} else if (descrithdevice. ACTION_FOUND.equals (intent. getAction () {// both incluthdevice and incluthclass are Parcelable subclass incluthdevice remoteDevice = intent. getParcelableExtra (effecthdevice. EXTRA_DEVICE); extends thclass = intent. getParcelableExtra (effecthd Evice. EXTRA_CLASS); if (remoteDevice! = Null & policthclass! = Null) {if (then thclass. getDeviceClass () = descrithclass. device. HEALTH_BLOOD_PRESSURE) {fig = remoteDevice; deviceList. add (remoteDevice); arrayAdapter. add (remoteDevice. getName (); descrithadapter. cancelDiscovery (); // find a suitable device and stop the discovery process. ACTION_ACL_CONNECTED.equals (intent. getAction () {descrithdevice currentDevice = intent. getParcelableExtra (effecthdevice. EXTRA_DEV ICE); Toast. makeText (MainActivity. this, currentDevice. getName () + "connected", Toast. LENGTH_SHORT ). show ();} else if (descrithdevice. ACTION_ACL_DISCONNECTED.equals (intent. getAction () {descrithdevice remoteDevice = intent. getParcelableExtra (effecthdevice. EXTRA_DEVICE); Toast. makeText (MainActivity. this, remoteDevice. getName () + "disconnected", Toast. LENGTH_SHORT ). show ();} else if (descrithdevice. ACTION_BOND_STATE_CHA NGED. equals (intent. getAction () {int bondState = intent. getIntExtra (effecthdevice. EXTRA_BOND_STATE, 0); if (bondState = descrithdevice. BOND_BONDED) {Toast. makeText (MainActivity. this, Build. MODEL + "successfully bound", Toast. LENGTH_SHORT ). show () ;}}}; ReadThread mReadThread;/** start this thread after receiving the broadcast from the device, execute read remote data and display */private class ReadThread extends Thread {@ Overridepublic void run () {super. run (); try {byte [] buffer = new byte [32]; int bytesRead =-1; listening = true; while (listening) {bytesRead = is. read (buffer); // IOExceptionif (bytesRead! =-1) {receiveData (buffer, bytesRead) ;}} catch (IOException e) {e. printStackTrace ();}}};}
<? Xml version = "1.0" encoding = "UTF-8"?> <LinearLayout android: layout_width = "match_parent" android: layout_height = "match_parent" android: orientation = "vertical" xmlns: android = "http://schemas.android.com/apk/res/android"> <Button android: id = "@ + id/discoverable" android: layout_width = "match_parent" android: layout_height = "wrap_content" android: text = "set current device visibility" android: onClick = "onClick"/> <Button android: id = "@ + id/discover" android: layout_width = "match_parent" android: layout_height = "wrap_content" android: text = "launch discovery process" android: onClick = "onClick"/> <Button android: id = "@ + id/accept" android: layout_width = "match_parent" android: layout_height = "wrap_content" android: text = "start anti-connection thread" android: onClick = "onClick"/> <EditText android: id = "@ + id/inbox" android: layout_width = "match_parent" android: layout_height = "wrap_content"/> <Button android: id = "@ + id/clearEdit" android: layout_width = "match_parent" android: layout_height = "wrap_content" android: onClick = "onClick" android: text = "clearEdit"/> <ListView android: id = "@ + id/listView" android: layout_width = "match_parent" android: layout_height = "wrap_content"/> </LinearLayout>