I can make my Nexus 7 tablet running Android 4.4.2 and Glass XE 17.2 exchange data without problem. You can run ClassicBluetoothServer.java either on Glass or another Android device, then run ClassicBluetoothClient.java on the other device. In the client code, you need to change CBT_SERVER_DEVICE_NAME's value to your paired Glass or Android device name (as seen in the device's Bluetooth Setting).
Client code:
public class ClassicBluetoothClient extends Activity {
public final static String TAG = "ClassicBluetoothClient";
public static final int REQUEST_TO_ENABLE_BT = 100;
private BluetoothAdapter mBluetoothAdapter;
private TextView mTvInfo;
private UUID MY_UUID = UUID.fromString("D04E3068-E15B-4482-8306-4CABFA1726E7");
private final static String FILE_PATH_RECEIVED = Environment.getExternalStorageDirectory().getPath() +"/filefromCBTserver";
// replace this with your own device names
private final static String CBT_SERVER_DEVICE_NAME = "Jeff Tang's Glass";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTvInfo = (TextView) findViewById(R.id.info);
mTvInfo.setText("Classic Bluetooth Client");
//mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.v(TAG, "Device does not support Bluetooth");
Toast.makeText(ClassicBluetoothClient.this, "Device does not support Bluetooth", Toast.LENGTH_LONG).show();
return;
}
else {
if (!mBluetoothAdapter.isEnabled()) {
Log.v(TAG, "Bluetooth supported but not enabled");
Toast.makeText(ClassicBluetoothClient.this, "Bluetooth supported but not enabled", Toast.LENGTH_LONG).show();
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_TO_ENABLE_BT);
}else{
Log.v(TAG, "Bluetooth supported and enabled");
// discover new Bluetooth devices
discoverBluetoothDevices();
// find devices that have been paired
getBondedDevices();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TO_ENABLE_BT) {
discoverBluetoothDevices();
getBondedDevices();
return;
}
}
void discoverBluetoothDevices () {
// register a BroadcastReceiver for the ACTION_FOUND Intent
// to receive info about each device discovered.
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
mBluetoothAdapter.startDiscovery();
}
// for each device discovered, the broadcast info is received
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.v(TAG, "BroadcastReceiver on Receive - " + device.getName() + ": " + device.getAddress());
String name = device.getName();
// found another Android device of mine and start communication
if (name != null && name.equalsIgnoreCase(CBT_SERVER_DEVICE_NAME)) {
new ConnectThread(device).start();
}
}
}
};
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
// bonded devices are those that have already paired with the current device sometime in the past (and have not been unpaired)
void getBondedDevices () {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
Log.v(TAG, "bonded device - " + device.getName() + ": " + device.getAddress());
if (device.getName().equalsIgnoreCase(CBT_SERVER_DEVICE_NAME)) {
Log.d(TAG, CBT_SERVER_DEVICE_NAME);
new ConnectThread(device).start();
break;
}
}
}
else {
Toast.makeText(ClassicBluetoothClient.this, "No bonded devices", Toast.LENGTH_LONG).show();
}
}
private class ConnectThread extends Thread {
int bytesRead;
int total;
private final BluetoothSocket mmSocket;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
Log.v(TAG, "before createRfcommSocketToServiceRecord");
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
Log.v(TAG, "after createRfcommSocketToServiceRecord");
} catch (IOException e) {
Log.v(TAG, " createRfcommSocketToServiceRecord exception: "+ e.getMessage());
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException e) {
Log.v(TAG, e.getMessage());
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
manageConnectedSocket(mmSocket);
}
private void manageConnectedSocket(BluetoothSocket socket) {
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
InputStream instream = socket.getInputStream();
fos = new FileOutputStream( FILE_PATH_RECEIVED );
bos = new BufferedOutputStream(fos);
bytesRead = -1;
total = 0;
while ((bytesRead = instream.read(buffer)) > 0) {
total += bytesRead;
bos.write(buffer, 0, bytesRead);
Log.i(TAG, "bytesRead="+bytesRead+",bufferSize="+bufferSize+",total="+total);
runOnUiThread(new Runnable() {
public void run() {
mTvInfo.setText("bytesRead="+bytesRead+", total="+total);
}
});
}
runOnUiThread(new Runnable() {
public void run() {
mTvInfo.setText(total + " bytes of file " + FILE_PATH_RECEIVED + "has been received");
}
});
bos.close();
socket.close();
} catch (IOException e) {
try {
socket.close();
bos.close();}
catch (IOException e2) {
Log.e(TAG, "socket close exception:", e2);
}
}
}
}
}
Server code:
public class ClassicBluetoothServer extends Activity {
public final static String TAG = "ClassicBluetoothServer";
BluetoothAdapter mBluetoothAdapter;
BluetoothServerSocket mBluetoothServerSocket;
public static final int REQUEST_TO_START_BT = 100;
public static final int REQUEST_FOR_SELF_DISCOVERY = 200;
private TextView mTvInfo;
UUID MY_UUID = UUID.fromString("D04E3068-E15B-4482-8306-4CABFA1726E7");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTvInfo = (TextView) findViewById(R.id.info);
// initialize Bluetooth and retrieve info about the BT radio interface
//mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
mTvInfo.setText("Device does not support Bluetooth");
return;
} else {
if (!mBluetoothAdapter.isEnabled()) {
mTvInfo.setText("Bluetooth supported but not enabled");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_TO_START_BT);
} else {
mTvInfo.setText("Bluetooth supported and enabled");
new AcceptThread().start();
}
}
}
private class AcceptThread extends Thread {
private BluetoothServerSocket mServerSocket;
public AcceptThread() {
try {
mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("ClassicBluetoothServer", MY_UUID);
}
catch (IOException e) {
final IOException ex = e;
runOnUiThread(new Runnable() {
public void run() {
mTvInfo.setText(ex.getMessage());
}
});
}
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
runOnUiThread(new Runnable() {
public void run() {
mTvInfo.setText(mTvInfo.getText() + "\n\nWaiting for Bluetooth Client ...");
}
});
socket = mServerSocket.accept(); // blocking call
} catch (IOException e) {
Log.v(TAG, e.getMessage());
break;
}
// If a connection was accepted
if (socket != null) {
// Do work in a separate thread
new ConnectedThread(socket).start();
try {
mServerSocket.close();
} catch (IOException e) {
Log.v(TAG, e.getMessage());
}
break;
}
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mSocket;
private final OutputStream mOutStream;
private int bytesRead;
final private String FILE_TO_BE_TRANSFERRED = "marchmadness.png";
final private String PATH = Environment.getExternalStorageDirectory().toString() + "/nbsocial/";
public ConnectedThread(BluetoothSocket socket) {
mSocket = socket;
OutputStream tmpOut = null;
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
mOutStream = tmpOut;
}
String copyAsset(String filename) {
File dir = new File(PATH);
if (!dir.exists()) {
if (!dir.mkdirs()) {
return null;
}
}
if (!(new File( PATH + filename).exists())) {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open(filename);
OutputStream out = new FileOutputStream(PATH + filename);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
Log.e(TAG, "Was unable to copy " + filename + e.toString());
return null;
}
}
return PATH + filename;
}
public void run() {
byte[] buffer = new byte[1024];
// transfer a file
if (mOutStream != null) {
File myFile = new File( copyAsset("test.png") );
FileInputStream fis = null;
try {
fis = new FileInputStream(myFile);
} catch (FileNotFoundException e) {
Log.e(TAG, e.getMessage());
}
BufferedInputStream bis = new BufferedInputStream(fis);
runOnUiThread(new Runnable() {
public void run() {
mTvInfo.setText(mTvInfo.getText() + "\nbefore sending file "+ PATH + FILE_TO_BE_TRANSFERRED + " of " + new File( PATH + FILE_TO_BE_TRANSFERRED ).length() + " bytes");
}
});
try {
bytesRead = 0;
for (int read = bis.read(buffer); read >= 0; read = bis.read(buffer))
{
mOutStream.write(buffer, 0, read);
bytesRead += read;
}
mSocket.close();
runOnUiThread(new Runnable() {
public void run() {
mTvInfo.setText(bytesRead + " bytes of file " + PATH + FILE_TO_BE_TRANSFERRED + " has been sent.");
}
});
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
new AcceptThread().start();
}
}
}