Back to project page Greenhouse2.0.
The source code is released under:
GNU General Public License
If you think the Android project Greenhouse2.0 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.megster.cordova; /*from w w w . j a v a2s . c om*/ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.os.Handler; import android.os.Message; import android.util.Log; import org.apache.cordova.CordovaArgs; import org.apache.cordova.api.*; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.Set; /** * PhoneGap Plugin for Serial Communication over Bluetooth */ public class BluetoothSerial extends CordovaPlugin { // actions private static final String LIST = "list"; private static final String CONNECT = "connect"; private static final String DISCONNECT = "disconnect"; private static final String WRITE = "write"; private static final String AVAILABLE = "available"; private static final String READ = "read"; private static final String READ_UNTIL = "readUntil"; private static final String SUBSCRIBE = "subscribe"; private static final String UNSUBSCRIBE = "unsubscribe"; private static final String IS_ENABLED = "isEnabled"; private static final String IS_CONNECTED = "isConnected"; private static final String CLEAR = "clear"; // callbacks private CallbackContext connectCallback; private CallbackContext dataAvailableCallback; private BluetoothAdapter bluetoothAdapter; private BluetoothSerialService bluetoothSerialService; // Debugging private static final String TAG = "BluetoothSerial"; private static final boolean D = true; // Message types sent from the BluetoothSerialService Handler public static final int MESSAGE_STATE_CHANGE = 1; public static final int MESSAGE_READ = 2; public static final int MESSAGE_WRITE = 3; public static final int MESSAGE_DEVICE_NAME = 4; public static final int MESSAGE_TOAST = 5; // Key names received from the BluetoothChatService Handler public static final String DEVICE_NAME = "device_name"; public static final String TOAST = "toast"; StringBuffer buffer = new StringBuffer(); private String delimiter; @Override public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException { LOG.d(TAG, "action = " + action); if (bluetoothAdapter == null) { bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } if (bluetoothSerialService == null) { bluetoothSerialService = new BluetoothSerialService(mHandler); } boolean validAction = true; if (action.equals(LIST)) { listBondedDevices(callbackContext); } else if (action.equals(CONNECT)) { connect(args, callbackContext); } else if (action.equals(DISCONNECT)) { connectCallback = null; bluetoothSerialService.stop(); callbackContext.success(); } else if (action.equals(WRITE)) { String data = args.getString(0); bluetoothSerialService.write(data.getBytes()); callbackContext.success(); } else if (action.equals(AVAILABLE)) { callbackContext.success(available()); } else if (action.equals(READ)) { callbackContext.success(read()); } else if (action.equals(READ_UNTIL)) { String interesting = args.getString(0); callbackContext.success(readUntil(interesting)); } else if (action.equals(SUBSCRIBE)) { delimiter = args.getString(0); dataAvailableCallback = callbackContext; PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT); result.setKeepCallback(true); callbackContext.sendPluginResult(result); } else if (action.equals(UNSUBSCRIBE)) { delimiter = null; dataAvailableCallback = null; callbackContext.success(); } else if (action.equals(IS_ENABLED)) { if (bluetoothAdapter.isEnabled()) { callbackContext.success(); } else { callbackContext.error("Bluetooth is disabled."); } } else if (action.equals(IS_CONNECTED)) { if (bluetoothSerialService.getState() == BluetoothSerialService.STATE_CONNECTED) { callbackContext.success(); } else { callbackContext.error("Not connected."); } } else if (action.equals(CLEAR)) { buffer.setLength(0); callbackContext.success(); } else { validAction = false; } return validAction; } @Override public void onDestroy() { super.onDestroy(); if (bluetoothSerialService != null) { bluetoothSerialService.stop(); } } private void listBondedDevices(CallbackContext callbackContext) throws JSONException { JSONArray deviceList = new JSONArray(); Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices(); for (BluetoothDevice device : bondedDevices) { JSONObject json = new JSONObject(); json.put("name", device.getName()); json.put("address", device.getAddress()); json.put("class", device.getBluetoothClass().getDeviceClass()); deviceList.put(json); } callbackContext.success(deviceList); } private void connect(CordovaArgs args, CallbackContext callbackContext) throws JSONException { String macAddress = args.getString(0); BluetoothDevice device = bluetoothAdapter.getRemoteDevice(macAddress); if (device != null) { connectCallback = callbackContext; bluetoothSerialService.connect(device, true); PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT); result.setKeepCallback(true); callbackContext.sendPluginResult(result); } else { callbackContext.error("Could not connect to " + macAddress); } } // The Handler that gets information back from the BluetoothSerialService // Original code used handler for the because it was talking to the UI. // Consider replacing with normal callbacks private final Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_READ: byte[] readBuf = (byte[]) msg.obj; String readMessage = new String(readBuf, 0, msg.arg1); buffer.append(readMessage); if (dataAvailableCallback != null) { sendDataToSubscriber(); } break; case MESSAGE_STATE_CHANGE: if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); switch (msg.arg1) { case BluetoothSerialService.STATE_CONNECTED: Log.i(TAG, "BluetoothSerialService.STATE_CONNECTED"); notifyConnectionSuccess(); break; case BluetoothSerialService.STATE_CONNECTING: Log.i(TAG, "BluetoothSerialService.STATE_CONNECTING"); break; case BluetoothSerialService.STATE_LISTEN: Log.i(TAG, "BluetoothSerialService.STATE_LISTEN"); break; case BluetoothSerialService.STATE_NONE: Log.i(TAG, "BluetoothSerialService.STATE_NONE"); break; } break; case MESSAGE_WRITE: // byte[] writeBuf = (byte[]) msg.obj; // String writeMessage = new String(writeBuf); // Log.i(TAG, "Wrote: " + writeMessage); break; case MESSAGE_DEVICE_NAME: Log.i(TAG, msg.getData().getString(DEVICE_NAME)); break; case MESSAGE_TOAST: String message = msg.getData().getString(TOAST); notifyConnectionLost(message); break; } } }; private void notifyConnectionLost(String error) { if (connectCallback != null) { connectCallback.error(error); connectCallback = null; } } private void notifyConnectionSuccess() { if (connectCallback != null) { PluginResult result = new PluginResult(PluginResult.Status.OK); result.setKeepCallback(true); connectCallback.sendPluginResult(result); } } private void sendDataToSubscriber() { String data = readUntil(delimiter); if (data != null && data.length() > 0) { PluginResult result = new PluginResult(PluginResult.Status.OK, data); result.setKeepCallback(true); dataAvailableCallback.sendPluginResult(result); } } private int available() { return buffer.length(); } private String read() { int length = buffer.length(); String data = buffer.substring(0, length); buffer.delete(0, length); return data; } private String readUntil(String c) { String data = ""; int index = buffer.indexOf(c, 0); if (index > -1) { data = buffer.substring(0, index + c.length()); buffer.delete(0, index + c.length()); } return data; } }