Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bind() with PIN. #406

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 75 additions & 24 deletions src/android/com/megster/cordova/BluetoothSerial.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class BluetoothSerial extends CordovaPlugin {
private static final String LIST = "list";
private static final String CONNECT = "connect";
private static final String CONNECT_INSECURE = "connectInsecure";
private static final String BIND = "bind";
private static final String DISCONNECT = "disconnect";
private static final String WRITE = "write";
private static final String AVAILABLE = "available";
Expand Down Expand Up @@ -119,6 +120,10 @@ public boolean execute(String action, CordovaArgs args, CallbackContext callback
boolean secure = false;
connect(args, secure, callbackContext);

} else if (action.equals(BIND)) {

bind(args, callbackContext);

} else if (action.equals(DISCONNECT)) {

connectCallback = null;
Expand Down Expand Up @@ -301,7 +306,7 @@ public void onReceive(Context context, Intent intent) {
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
try {
JSONObject o = deviceToJSON(device);
JSONObject o = deviceToJSON(device);
unpairedDevices.put(o);
if (ddc != null) {
PluginResult res = new PluginResult(PluginResult.Status.OK, o);
Expand Down Expand Up @@ -354,28 +359,74 @@ private void connect(CordovaArgs args, boolean secure, CallbackContext callbackC
}
}

private void bind(CordovaArgs args, CallbackContext callbackContext) throws JSONException {
String macAddress = args.getString(0);
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(macAddress);
if (device == null) {
Log.e(TAG, "Unknown device: " + macAddress);
callbackContext.error("Could not bind with " + macAddress);
return;
}

String Pin = args.getString(1);

final BroadcastReceiver pairingReceiver = new BroadcastReceiver() {

public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
int previousState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, 0);
int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 0);
Log.d(TAG, "Received: " + action + " previous: " + previousState + " current: " + bondState);
if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
Log.d(TAG, "Setting the PIN");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
byte[] pinBytes = Pin.getBytes();
device.setPin(pinBytes);
device.setPairingConfirmation(true);
}
if (bondState == BluetoothDevice.BOND_BONDED)
callbackContext.success("PAIRED correctly");
else if (bondState == BluetoothDevice.BOND_NONE)
callbackContext.error("PAIR failed because of state:" + bondState);
if (bondState == BluetoothDevice.BOND_BONDED || bondState == BluetoothDevice.BOND_NONE)
cordova.getActivity().unregisterReceiver(this);
}
};

Activity activity = cordova.getActivity();
activity.registerReceiver(pairingReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
activity.registerReceiver(pairingReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST));
activity.registerReceiver(pairingReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));

if (!device.createBond()) {
Log.e(TAG, "Somehow unable to createBound(). Already bound ?");
callbackContext.success("PAIRED already");
}

}

// 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:
buffer.append((String)msg.obj);
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_READ:
buffer.append((String) msg.obj);

if (dataAvailableCallback != null) {
sendDataToSubscriber();
}
if (dataAvailableCallback != null) {
sendDataToSubscriber();
}

break;
case MESSAGE_READ_RAW:
if (rawDataAvailableCallback != null) {
byte[] bytes = (byte[]) msg.obj;
sendRawDataToSubscriber(bytes);
}
break;
case MESSAGE_STATE_CHANGE:
break;
case MESSAGE_READ_RAW:
if (rawDataAvailableCallback != null) {
byte[] bytes = (byte[]) msg.obj;
sendRawDataToSubscriber(bytes);
}
break;
case MESSAGE_STATE_CHANGE:

if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
Expand Down Expand Up @@ -469,22 +520,22 @@ private String readUntil(String c) {
public void onRequestPermissionResult(int requestCode, String[] permissions,
int[] grantResults) throws JSONException {

for(int result:grantResults) {
if(result == PackageManager.PERMISSION_DENIED) {
for (int result : grantResults) {
if (result == PackageManager.PERMISSION_DENIED) {
LOG.d(TAG, "User *rejected* location permission");
this.permissionCallback.sendPluginResult(new PluginResult(
PluginResult.Status.ERROR,
"Location permission is required to discover unpaired devices.")
);
);
return;
}
}

switch(requestCode) {
case CHECK_PERMISSIONS_REQ_CODE:
LOG.d(TAG, "User granted location permission");
discoverUnpairedDevices(permissionCallback);
break;
switch (requestCode) {
case CHECK_PERMISSIONS_REQ_CODE:
LOG.d(TAG, "User granted location permission");
discoverUnpairedDevices(permissionCallback);
break;
}
}
}
9 changes: 7 additions & 2 deletions www/bluetoothSerial.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ module.exports = {
cordova.exec(success, failure, "BluetoothSerial", "connectInsecure", [macAddress]);
},

// Android only
bind: function (macAddress, pin, success, failure) {
cordova.exec(success, failure, "BluetoothSerial", "bind", [macAddress, pin]);
},

disconnect: function (success, failure) {
cordova.exec(success, failure, "BluetoothSerial", "disconnect", []);
},
Expand Down Expand Up @@ -72,7 +77,7 @@ module.exports = {
// calls the success callback when new data is available with an ArrayBuffer
subscribeRawData: function (success, failure) {

successWrapper = function(data) {
successWrapper = function (data) {
// Windows Phone flattens an array of one into a number which
// breaks the API. Stuff it back into an ArrayBuffer.
if (typeof data === 'number') {
Expand Down Expand Up @@ -134,7 +139,7 @@ module.exports = {

};

var stringToArrayBuffer = function(str) {
var stringToArrayBuffer = function (str) {
var ret = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
ret[i] = str.charCodeAt(i);
Expand Down