Skip to content

Commit 9a937e8

Browse files
committed
Handle USB permission through a broadcast receiver.
1 parent 3f4d532 commit 9a937e8

File tree

2 files changed

+99
-49
lines changed

2 files changed

+99
-49
lines changed

src/android/org/stereolux/cordova/serial/Serial.java

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import android.app.PendingIntent;
1313
import android.content.Context;
1414
import android.content.Intent;
15+
import android.content.IntentFilter;
1516
import android.hardware.usb.UsbDevice;
1617
import android.hardware.usb.UsbDeviceConnection;
1718
import android.hardware.usb.UsbManager;
@@ -24,19 +25,16 @@
2425
/**
2526
* Cordova plugin to communicate with the android serial port
2627
* @author Xavier Seignard <[email protected]>
27-
* @version 0.0.1
2828
*/
2929
public class Serial extends CordovaPlugin {
3030
// logging tag
3131
private final String TAG = Serial.class.getSimpleName();
3232
// actions definitions
33-
public static final String ACTION_REQUEST_PERMISSION = "requestPermission";
34-
public static final String ACTION_OPEN = "openSerial";
35-
public static final String ACTION_READ = "readSerial";
36-
public static final String ACTION_WRITE = "writeSerial";
37-
public static final String ACTION_CLOSE = "closeSerial";
38-
// flag to check if the user has permitted to use the USB/serial port
39-
private boolean permitted = false;
33+
private static final String ACTION_REQUEST_PERMISSION = "requestPermission";
34+
private static final String ACTION_OPEN = "openSerial";
35+
private static final String ACTION_READ = "readSerial";
36+
private static final String ACTION_WRITE = "writeSerial";
37+
private static final String ACTION_CLOSE = "closeSerial";
4038
// UsbManager instance to deal with permission and opening
4139
private UsbManager manager;
4240
// The current driver that handle the serial port
@@ -103,17 +101,15 @@ public void run() {
103101
driver = availableDrivers.get(0);
104102
UsbDevice device = driver.getDevice();
105103
// create the intent that will be used to get the permission
106-
PendingIntent pendingIntent = PendingIntent.getBroadcast(cordova.getActivity(), 0, new Intent("USB_PERMISSION"), 0);
104+
PendingIntent pendingIntent = PendingIntent.getBroadcast(cordova.getActivity(), 0, new Intent(UsbBroadcastReceiver.USB_PERMISSION), 0);
105+
// and a filter on the permission we ask
106+
IntentFilter filter = new IntentFilter();
107+
filter.addAction(UsbBroadcastReceiver.USB_PERMISSION);
108+
// this broadcast receiver will handle the permission results
109+
UsbBroadcastReceiver usbReceiver = new UsbBroadcastReceiver(callbackContext, cordova.getActivity());
110+
cordova.getActivity().registerReceiver(usbReceiver, filter);
111+
// finally ask for the permission
107112
manager.requestPermission(device, pendingIntent);
108-
if (manager.hasPermission(device)) {
109-
permitted = true;
110-
Log.d(TAG, "Permission to connect to the device was accepted!");
111-
callbackContext.success("Permission to connect to the device was accepted!");
112-
}
113-
else {
114-
Log.d(TAG, "Permission to connect to the device was denied!");
115-
callbackContext.error("Permission to connect to the device was denied!");
116-
}
117113
}
118114
else {
119115
// no available drivers
@@ -132,41 +128,35 @@ public void run() {
132128
private void openSerial(final JSONObject opts, final CallbackContext callbackContext) {
133129
cordova.getThreadPool().execute(new Runnable() {
134130
public void run() {
135-
if (permitted) {
136-
UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
137-
if (connection != null) {
138-
// get first port and open it
139-
port = driver.getPorts().get(0);
140-
try {
141-
port.open(connection);
142-
// get connection params or the default values
143-
int baudRate = opts.has("baudRate") ? opts.getInt("baudRate") : 9600;
144-
int dataBits = opts.has("dataBits") ? opts.getInt("dataBits") : UsbSerialPort.DATABITS_8;
145-
int stopBits = opts.has("stopBits") ? opts.getInt("stopBits") : UsbSerialPort.STOPBITS_1;
146-
int parity = opts.has("parity") ? opts.getInt("parity") : UsbSerialPort.PARITY_NONE;
147-
port.setParameters(baudRate, dataBits, stopBits, parity);
148-
}
149-
catch (IOException e) {
150-
// deal with error
151-
Log.d(TAG, e.getMessage());
152-
callbackContext.error(e.getMessage());
153-
}
154-
catch (JSONException e) {
155-
// deal with error
156-
Log.d(TAG, e.getMessage());
157-
callbackContext.error(e.getMessage());
158-
}
159-
Log.d(TAG, "Serial port opened!");
160-
callbackContext.success("Serial port opened!");
131+
UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
132+
if (connection != null) {
133+
// get first port and open it
134+
port = driver.getPorts().get(0);
135+
try {
136+
port.open(connection);
137+
// get connection params or the default values
138+
int baudRate = opts.has("baudRate") ? opts.getInt("baudRate") : 9600;
139+
int dataBits = opts.has("dataBits") ? opts.getInt("dataBits") : UsbSerialPort.DATABITS_8;
140+
int stopBits = opts.has("stopBits") ? opts.getInt("stopBits") : UsbSerialPort.STOPBITS_1;
141+
int parity = opts.has("parity") ? opts.getInt("parity") : UsbSerialPort.PARITY_NONE;
142+
port.setParameters(baudRate, dataBits, stopBits, parity);
143+
}
144+
catch (IOException e) {
145+
// deal with error
146+
Log.d(TAG, e.getMessage());
147+
callbackContext.error(e.getMessage());
161148
}
162-
else {
163-
Log.d(TAG, "Cannot connect to the device!");
164-
callbackContext.error("Cannot connect to the device!");
149+
catch (JSONException e) {
150+
// deal with error
151+
Log.d(TAG, e.getMessage());
152+
callbackContext.error(e.getMessage());
165153
}
154+
Log.d(TAG, "Serial port opened!");
155+
callbackContext.success("Serial port opened!");
166156
}
167157
else {
168-
Log.d(TAG, "Permission to connect to the device was denied!");
169-
callbackContext.error("Permission to connect to the device was denied!");
158+
Log.d(TAG, "Cannot connect to the device!");
159+
callbackContext.error("Cannot connect to the device!");
170160
}
171161
}
172162
});
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.stereolux.cordova.serial;
2+
3+
import org.apache.cordova.CallbackContext;
4+
5+
import android.app.Activity;
6+
import android.content.BroadcastReceiver;
7+
import android.content.Context;
8+
import android.content.Intent;
9+
import android.hardware.usb.UsbManager;
10+
import android.util.Log;
11+
12+
/**
13+
* Custom {@link BroadcastReceiver} that can talk through a cordova {@link CallbackContext}
14+
* @author Xavier Seignard <[email protected]>
15+
*/
16+
public class UsbBroadcastReceiver extends BroadcastReceiver {
17+
// logging tag
18+
private final String TAG = UsbBroadcastReceiver.class.getSimpleName();
19+
// usb permission tag name
20+
public static final String USB_PERMISSION ="org.stereolux.cordova.serial.USB_PERMISSION";
21+
// cordova callback context to notify the success/error to the cordova app
22+
private CallbackContext callbackContext;
23+
// cordova activity to use it to unregister this broadcast receiver
24+
private Activity activity;
25+
26+
/**
27+
* Custom broadcast receiver that will handle the cordova callback context
28+
* @param callbackContext
29+
* @param activity
30+
*/
31+
public UsbBroadcastReceiver(CallbackContext callbackContext, Activity activity) {
32+
this.callbackContext = callbackContext;
33+
this.activity = activity;
34+
}
35+
36+
37+
/**
38+
* Handle permission answer
39+
* @param context
40+
* @param intent
41+
* @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
42+
*/
43+
@Override
44+
public void onReceive(Context context, Intent intent) {
45+
String action = intent.getAction();
46+
if (USB_PERMISSION.equals(action)) {
47+
// deal with the user answer about the permission
48+
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
49+
Log.d(TAG, "Permission to connect to the device was accepted!");
50+
callbackContext.success("Permission to connect to the device was accepted!");
51+
}
52+
else {
53+
Log.d(TAG, "Permission to connect to the device was denied!");
54+
callbackContext.error("Permission to connect to the device was denied!");
55+
}
56+
// unregister the broadcast receiver since it's no longer needed
57+
activity.unregisterReceiver(this);
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)