I need to send file to a computer instead of another android application. I have looked at the bluetooth api, but it only allow connection as client-server. In my case I dont know what UUId would be on the computer. Do I need to look at obex. I haven't used it before. So any help would be benficial.
How to send file using bluetooth on android programatically?
25.9k Views Asked by Saqib AtThere are 5 best solutions below
On
For Ice Cream Sandwich this code is not working so you have to use this code
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
Intent sharingIntent = new Intent(
android.content.Intent.ACTION_SEND);
sharingIntent.setType("image/jpeg");
sharingIntent
.setComponent(new ComponentName(
"com.android.bluetooth",
"com.android.bluetooth.opp.BluetoothOppLauncherActivity"));
sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(sharingIntent);
} else {
ContentValues values = new ContentValues();
values.put(BluetoothShare.URI, uri.toString());
Toast.makeText(getBaseContext(), "URi : " + uri,
Toast.LENGTH_LONG).show();
values.put(BluetoothShare.DESTINATION, deviceAddress);
values.put(BluetoothShare.DIRECTION,
BluetoothShare.DIRECTION_OUTBOUND);
Long ts = System.currentTimeMillis();
values.put(BluetoothShare.TIMESTAMP, ts);
getContentResolver().insert(BluetoothShare.CONTENT_URI,
values);
}
On
You can use the obex library. It seemed that android didn't provide the obex library, but I solved the problem and the solution is posted here.
Further Explanation (please start reading from here if you're busy)
- I was trying to create an android phone remote controller (and something similar to telnet server) which helps controlling the phone remotely with my old feature phone.
Main content :Bluetooth FTP client
My first plan was to make the app check the list of files of my feature phone's directory.
But I didn't know how to connect to my feature phone's ftp server.
I googled a lot about how to connect to a ftp server via bluetooth but I could only find that Bluetoorh FTP server used the
OBEX Protocol.I found a useful material (PDF file) in a SO thread and studied about OBEX connect requests, put and get operations.
So I finally wrote some codes that tries to connect to the
Bluetooth FTPserver. I want to show them to you, but I lost it :( The codes were like just directly writting byte sequences to the output stream.I also had difficult time finding out what UUID makes the app connect as FTP client. But I tried every UUIDs retrieved using the code below.
String parcels=""; ParcelUuid[] uuids=mBtDevice.getUuids(); int i=0; for (ParcelUuid p:uuids) { parcels += "UUID UUID" + new Integer(i).toString() + "=UUID.fromString((\"" + p.getUuid().toString() + "\"));\n\n"; ++i; }Nothing seemed to bring me to the answer I wanted. So I googled more and found out that I not only should I use UUID 00001106-0000-1000-8000-00805f9b34fb to connect to OBEX FTP server, but also shold I transmit target header ** with UUID **F9EC7BC4-953C-11D2-984E-525400DC9E09 when sending
OBEX connectrequest. The code below shows how to connect to a bluetooth FTP server as a client.try { mBtSocket = mBtDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(" 00001106-0000-1000-8000-00805f9b34fb")); } catch (Exception e) { //e.printStackTrace(); } Thread thread=new Thread(new Runnable() { public void run() { UUID uuid=UUID.fromString("F9EC7BC4-953C-11D2-984E-525400DC9E09"); ByteBuffer bb = ByteBuffer.wrap(new byte[16]); bb.putLong(uuid.getMostSignificantBits()); bb.putLong(uuid.getLeastSignificantBits()); byte [] bytes=bb.array(); Operation putOperation=null; Operation getOperation=null; try { // connect the socket mBtSocket.connect(); //I will explain below mSession = new ClientSession((ObexTransport)(mTransport = new BluetoothObexTransport(mBtSocket))); HeaderSet headerset = new HeaderSet(); headerset.setHeader(HeaderSet.TARGET, bytes); headerset = mSession.connect(headerset); if (headerset.getResponseCode() == ResponseCodes.OBEX_HTTP_OK) { mConnected = true; } else { mSession.disconnect(headerset); } ...
Then you are now connected as FTP client and are ready to use OBEX operations to send files, request for files, list directories, etc.
- However I didn't want to wait an hour to send my command to my android phone. (And it would be inefficient if I increase frequency of polling, as every polling methods are.)
Start reading from here if you are busy Main content: OBEX OPP
For the reason I mentioned above, I greedly searched for ways to manipulate OPP which I discovered from the OBEX documentation.
You may want to transfer files via bluetooth normally (without defining your protocol and building a new desktop application just for it) to your computer, right? Then sending to OBEX OPP inbox service that is running natively on your desktop windows computer is the best solution. So how can we connect to the OPP (Obex Object Push) inbox service?
- Setup OBEX library
Add
import javax.obex;to your source code. If your compiler doesn't support OBEX library, download sources and add to your project from here. - Implement
ObexTransportYou should provide a class that implementsObexTransportto the library when you use it. It defines how the library should send data (like by RFCOMM, TCP,...). A sample implementation is here. This can cause some runtime or compilation errors such asthere's no method. But you can partially fix those by replacing the method calls to constants likereturn 4096instead ofreturn mSocket.getMaxTransmitPacketSize();, outcommenting theifstatements ofpublic int getMaxTransmitPacketSize(). Or you can try using reflection to get those methods runtime. - Get
BluetoothSocketGet a bluetooth socket usingmBtDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(" 00001105-0000-1000-8000-00805f9b34fb" ));And callconnect(). - Create
ClientSessionCreate a instance of yourObexTransportimplementation, and create a newClientSessionlikemSession = new ClientSession((ObexTransport)(mTransport = new BluetoothObexTransport(mBtSocket)));. Send OBEX connect request to your computer OPP inbox service.
HeaderSet headerset = new HeaderSet(); // headerset.setHeader(HeaderSet.COUNT,n); headerset = mSession.connect(null); if (headerset.getResponseCode() == ResponseCodes.OBEX_HTTP_OK) { mConnected = true; }Send OBEX put requests using the
ClientSession.protected boolean Put(ClientSession session, byte[] bytes, String as, String type) { // TODO: Implement this method //byte [] bytes; String filename=as; boolean retry=true; int times=0; while (retry && times < 4) { Operation putOperation=null; OutputStream mOutput = null; //ClientSession mSession = null; //ArrayUtils.reverse(bytes); try { // Send a file with meta data to the server final HeaderSet hs = new HeaderSet(); hs.setHeader(HeaderSet.NAME, filename); hs.setHeader(HeaderSet.TYPE, type); hs.setHeader(HeaderSet.LENGTH, new Long((long)bytes.length)); Log.v(TAG,filename); //Log.v(TAG,type); Log.v(TAG,bytes.toString()); putOperation = session.put(hs); mOutput = putOperation.openOutputStream(); mOutput.write(bytes); mOutput.close(); putOperation.close(); } catch (Exception e) { Log.e(TAG, "put failed", e); retry = true; times++; continue; //e.printStackTrace(); } finally { try { if(mOutput!=null) mOutput.close(); if(putOperation!=null) putOperation.close(); } catch (Exception e) { Log.e(TAG, "put finally" , e); retry = true; times++; continue; } //updateStatus("[CLIENT] Connection Closed"); } retry = false; return true; } return false; }Finally, disconnect.
private void FinishBatch(ClientSession mSession) throws IOException { mSession.disconnect(null); try { Thread.sleep((long)500); } catch (InterruptedException e) {} mBtSocket.close(); }Then here is a wrapper class.
import android.bluetooth.*; import android.util.*; import java.io.*; import java.util.*; import javax.obex.*; public class BluetoothOPPHelper { String address; BluetoothAdapter mBtadapter; BluetoothDevice device; ClientSession session; BluetoothSocket mBtSocket; protected final UUID OPPUUID=UUID.fromString(("00001105-0000-1000-8000-00805f9b34fb")); private String TAG="BluetoothOPPHelper"; public BluetoothOPPHelper(String address) { mBtadapter=BluetoothAdapter.getDefaultAdapter(); device=mBtadapter.getRemoteDevice(address); try { mBtSocket = device.createRfcommSocketToServiceRecord(OPPUUID); } catch (IOException e) { throw new RuntimeException(e); } } public ClientSession StartBatch(int n) { ClientSession mSession = null; // TODO: Implement this method boolean retry=true; int times=0; while (retry && times < 4) { //BluetoothConnector.BluetoothSocketWrapper bttmp=null; try { mBtSocket.connect(); //bttmp = (new BluetoothConnector(device,false,BluetoothAdapter.getDefaultAdapter(),Arrays.asList(new UUID[]{OPPUUID,OPPUUID, OPPUUID}))).connect();//*/ device.createInsecureRfcommSocketToServiceRecord(OPPUUID); /*if(mBtSocket.isConnected()) { mBtSocket.close(); }*/ } catch (Exception e) { Log.e(TAG, "opp fail sock " + e.getMessage()); retry = true; times++; continue; } try { //mBtSocket=bttmp.getUnderlyingSocket(); // mBtSocket.connect(); BluetoothObexTransport mTransport = null; mSession = new ClientSession((ObexTransport)(mTransport = new BluetoothObexTransport(mBtSocket))); HeaderSet headerset = new HeaderSet(); // headerset.setHeader(HeaderSet.COUNT,n); headerset = mSession.connect(null); if (headerset.getResponseCode() == ResponseCodes.OBEX_HTTP_OK) { boolean mConnected = true; } else { Log.e(TAG, "SEnd by OPP denied;"); mSession.disconnect(headerset); times++; continue; } } catch (Exception e) { Log.e(TAG, "opp failed;" , e); retry = true; times++; continue; //e.rintStackTrace(); } retry=false; } return mSession; } protected boolean Put(ClientSession session, byte[] bytes, String as, String type) { // TODO: Implement this method //byte [] bytes; String filename=as; boolean retry=true; int times=0; while (retry && times < 4) { Operation putOperation=null; OutputStream mOutput = null; //ClientSession mSession = null; //ArrayUtils.reverse(bytes); try { // Send a file with meta data to the server final HeaderSet hs = new HeaderSet(); hs.setHeader(HeaderSet.NAME, filename); hs.setHeader(HeaderSet.TYPE, type); hs.setHeader(HeaderSet.LENGTH, new Long((long)bytes.length)); Log.v(TAG,filename); //Log.v(TAG,type); Log.v(TAG,bytes.toString()); putOperation = session.put(hs); mOutput = putOperation.openOutputStream(); mOutput.write(bytes); mOutput.close(); putOperation.close(); } catch (Exception e) { Log.e(TAG, "put failed", e); retry = true; times++; continue; //e.printStackTrace(); } finally { try { if(mOutput!=null) mOutput.close(); if(putOperation!=null) putOperation.close(); } catch (Exception e) { Log.e(TAG, "put finally" , e); retry = true; times++; continue; } //updateStatus("[CLIENT] Connection Closed"); } retry = false; return true; } return false; } protected boolean Put(ClientSession s, OPPBatchInfo info) { return Put(s,info.data,info.as,info.type); } private void FinishBatch(ClientSession mSession) throws IOException { mSession.disconnect(null); try { Thread.sleep((long)500); } catch (InterruptedException e) {} mBtSocket.close(); } public boolean flush() throws IOException { if (sendQueue.isEmpty()) { return true; } try { Thread.sleep((long)2000); } catch (InterruptedException e) {} ClientSession session=StartBatch(sendQueue.size()); if (session == null) { return false; } while (!sendQueue.isEmpty()) { if (Put(session, sendQueue.remove()) == false) { Log.e(TAG, "Put failed"); } } FinishBatch(session); return true; } Queue<OPPBatchInfo> sendQueue; public boolean AddTransfer(String as,String mimetype,byte[] data) { return sendQueue.add(new OPPBatchInfo(as,mimetype,data)); } class OPPBatchInfo { String as; String type; byte[] data; public OPPBatchInfo(String as,String type,byte[] data) { this.as=as; this.data=data; this.type=type; } } }
On
You need to implement FTP over OBEX. Once you implement the standard protocol and profile, your Android FTP implementation will inter-operate with virtually any Bluetooth FTP server. You'll also need to implement OPP for maximum inter-operability. The OBEX protocol is not so difficult to implement and the specs is freely available.
On
I know this question is old, but for anyone having to deal with this still:
With this library you can send files via OBEX and commands via RFCOMM: https://github.com/ddibiasi/Funker
Once connected to your target device, you can manipulate its filesystem.
The following example sends a file:
val rxOBEX = RxObex(device)
rxOBEX
.putFile("rubberduck.txt", "text/plain", "oh hi mark".toByteArray(), "example/directory") // Name of file, mimetype, bytes of file, directory
.subscribeBy(
onComplete = {
Log.d(TAG, "Succesfully sent a testfile to device")
},
onError = { e ->
Log.e(TAG, "Received error!")
}
)
The library is built on Rx, so all calls are non blocking.
Try this. I can send a file using this code.
Code of BluetoothShare.java