{"id":1481,"date":"2012-10-09T21:40:56","date_gmt":"2012-10-09T18:40:56","guid":{"rendered":"http:\/\/9v.lt\/blog\/?p=1481"},"modified":"2022-01-19T08:34:41","modified_gmt":"2022-01-19T06:34:41","slug":"three-ways-to-send-data-over-bluetooth-with-android","status":"publish","type":"post","link":"https:\/\/9v.lt\/blog\/three-ways-to-send-data-over-bluetooth-with-android\/","title":{"rendered":"Three ways to send data over bluetooth with android"},"content":{"rendered":"<p>My recent app that I am developing involves bluetooth and I had to do quite some research about the whole thing and the android API. I had to do lots of searching, but in the end it was ok.<br \/>\nAnyway, while I was searching I had to scrape bits and pieces from every corner of the internet and put them together, so I decided I&#8217;ll make one general post about ways to send data over bluetooth in android. I&#8217;ll explain everything as we go.<br \/>\n<!--more--><br \/>\n<br \/>\nLet&#8217;s start from the easiest one:<\/p>\n<pre lang=\"java\">\r\nIntent intent = new Intent();  \r\nintent.setAction(Intent.ACTION_SEND);   \r\nintent.setType(\"image\/*\");\r\nintent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(\"somefile.mp3\")));\r\nstartActivity(intent);\r\n<\/pre>\n<p>This is a more intuitive way than the rest 3 but you has the least control with it. What this does is prompt the user which application to use to open the file with &#8211; it displays a list. Of course the user selects Bluetooth and then it displays bluetooth settings where the user picks out the device and the transfer is initiated. Needless to say it uses in-built services.<br \/>\nGood for simple things, but isn&#8217;t very professional. Also you cannot send any file type you want because of the MIME types.<\/p>\n<p>A bit more complicated is the next snippet:<\/p>\n<pre lang=\"java\">\r\nContentValues values = new ContentValues();\r\nString address = device.getAddress();\r\nvalues.put(BluetoothShare.URI, Uri.fromFile(new File(\"somefile.mp3\")).toString());\r\nvalues.put(BluetoothShare.DESTINATION, address);\r\nvalues.put(BluetoothShare.DIRECTION, BluetoothShare.DIRECTION_OUTBOUND);\r\nLong ts = System.currentTimeMillis();\r\nvalues.put(BluetoothShare.TIMESTAMP, ts);\r\nUri contentUri = getContentResolver().insert(BluetoothShare.CONTENT_URI, values);\r\n<\/pre>\n<p>To use this snippet, you will need <a href=\"http:\/\/source-android.frandroid.com\/packages\/apps\/Bluetooth\/src\/com\/android\/bluetooth\/opp\/BluetoothShare.java\" target=\"_blank\" rel=\"noopener\">this<\/a> class. Save it as <em>BluetoothShare.java<\/em>.<br \/>\nNow this snippet is a bit more professional. It still uses the in-built bluetooth service and I heard it doesn&#8217;t work on many devices, but no one has confirmed that.<br \/>\nThis snippet doesn&#8217;t prompt the user for action, instead it sends the data to a ContentResolver then it gets re-routed to the Bluetooth service and put into the stack. From there the file transfer is programatically initiated.<br \/>\nIt&#8217;s good for sending a file, but you don&#8217;t have much control over the process &#8211; you cannot programatically cancel the transfer, you cannot empty the stack, you cannot receive feedback through callbacks&#8230; Once the last line is executed you don&#8217;t have control any more.<br \/>\nStill for file transfer it&#8217;s the best solution and you can send any kind of file you want, as long as the receiver accepts it.<\/p>\n<p>Last snippet is the hardest:<\/p>\n<pre lang=\"java\">\r\npublic void sendFile(Uri uri, BluetoothSocket bs) throws IOException {\r\n\tBufferedInputStream bis = new BufferedInputStream(getContentResolver().openInputStream(uri));\r\n\tOutputStream os = bs.getOutputStream();\r\n    try {\r\n        int bufferSize = 1024;\r\n        byte[] buffer = new byte[bufferSize];\r\n\r\n        \/\/ we need to know how may bytes were read to write them to the byteBuffer\r\n        int len = 0;\r\n        while ((len = bis.read(buffer)) != -1) {\r\n            os.write(buffer, 0, len);\r\n        }\r\n    } finally {\r\n    \tbis.close();\r\n        os.flush();\r\n        os.close();\r\n        bs.close();\r\n    }\r\n}\r\n<\/pre>\n<p>Needless to say that this only works if you have the Client-Server architecture on both your devices.<br \/>\nTo use this, you need to initiate a connection to the device and call this method passing the file URI and active socket as a parameter. It converts the file in chunks and writes them to the stream.<\/p>\n<p>Looks simple, but it is completely different from the first two snippets because it uses the socket to send and receive data which establishes the <a href=\"http:\/\/en.wikipedia.org\/wiki\/RFCOMM#Radio_frequency_communication_.28RFCOMM.29\" target=\"_blank\" rel=\"noopener\">RFCOMM<\/a> channel. In-built services use an <em><a href=\"http:\/\/en.wikipedia.org\/wiki\/Bluetooth_profile#Object_Push_Profile_.28OPP.29\" target=\"_blank\" rel=\"noopener\">OBEX OPP<\/a><\/em> mode which have its own packets and headers. You can read more on <em>OBEX PUSH<\/em> profile in <a href=\"https:\/\/www.bluetooth.org\/docman\/handlers\/DownloadDoc.ashx?doc_id=8706\" target=\"_blank\" rel=\"noopener\">this document<\/a> (specifically what kind of headers must be included are defined on page 21).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My recent app that I am developing involves bluetooth and I had to do quite<\/p>\n","protected":false},"author":2,"featured_media":1658,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[135,836,837],"class_list":["post-1481","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-eng","category-my-tutos","tag-android","tag-bluetooth","tag-transfer"],"_links":{"self":[{"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/posts\/1481","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/comments?post=1481"}],"version-history":[{"count":0,"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/posts\/1481\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/media\/1658"}],"wp:attachment":[{"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/media?parent=1481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/categories?post=1481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/9v.lt\/blog\/wp-json\/wp\/v2\/tags?post=1481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}