-
Notifications
You must be signed in to change notification settings - Fork 55
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 Bluetooth Support for iOS, extend support for Android #15
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ | |
import android.bluetooth.BluetoothAdapter; | ||
import android.bluetooth.BluetoothDevice; | ||
import android.content.BroadcastReceiver; | ||
import android.content.ComponentName; | ||
import android.content.Context; | ||
import android.content.Intent; | ||
import android.content.IntentFilter; | ||
|
@@ -36,6 +37,7 @@ | |
import android.graphics.BitmapFactory; | ||
import android.os.Build; | ||
import android.preference.PreferenceManager; | ||
import android.provider.Settings; | ||
import android.telecom.Call; | ||
import android.util.Base64; | ||
import android.util.Log; | ||
|
@@ -55,8 +57,8 @@ | |
|
||
public class BrotherPrinter extends CordovaPlugin { | ||
private static PrinterInfo.Model[] supportedModels = { | ||
PrinterInfo.Model.QL_720NW, | ||
PrinterInfo.Model.QL_820NWB, | ||
PrinterInfo.Model.QL_720NW, | ||
PrinterInfo.Model.QL_820NWB, | ||
}; | ||
|
||
private MsgHandle mHandle; | ||
|
@@ -93,6 +95,11 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) { | |
@Override | ||
public boolean execute (String action, JSONArray args, CallbackContext callbackContext) throws JSONException { | ||
|
||
if ("pairBluetoothPrinters".equals(action)) { | ||
pairBluetoothPrinters(callbackContext); | ||
return true; | ||
} | ||
|
||
if ("findNetworkPrinters".equals(action)) { | ||
findNetworkPrinters(callbackContext); | ||
return true; | ||
|
@@ -290,6 +297,20 @@ private void sendDiscoveredPrinters(final CallbackContext callbackctx, List<Disc | |
callbackctx.sendPluginResult(result); | ||
} | ||
|
||
private static final int OPEN_BLUETOOTH_SETTINGS_REQUEST = 0x2345; | ||
private void pairBluetoothPrinters(final CallbackContext callbackctx) { | ||
cordova.getThreadPool().execute(new Runnable() { | ||
@Override | ||
public void run() { | ||
final Intent openPairSection = new Intent(); | ||
openPairSection.setAction(Settings.ACTION_BLUETOOTH_SETTINGS); | ||
cordova.startActivityForResult(BrotherPrinter.this, openPairSection, OPEN_BLUETOOTH_SETTINGS_REQUEST); | ||
|
||
callbackctx.success(); | ||
} | ||
}); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't we just use BluetoothManager.getAdapter() to get BluetoothAdapter along with BluetoothDevice. Listen for: ACTION_DISCOVERY_STARTED, ACTION_DISCOVERY_FINISHED, and ACTION_FOUND. Then call BluetoothAdapter.startDiscovery(). Then when you find a brother device via ACTION_FOUND, simply call: BluetoothAdapter.getRemoteDevice() to get a BluetoothDevice. Then on the device returned from getRemoteDevice(), issue a createBond() call: BluetoothDevice.createBond(). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alternatively... this may provide some insight too, though probably overkill for what we need here https://github.com/tanelih/phonegap-bluetooth-plugin this is an android-only plugin for old phonegap, but the android bits should be usable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can make this better on android with a new ticket though... if you want to stick to IOS here. lemme know... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could probably use As far as the Unless you're saying you just want to find the first printer you can find and try to bond with it immediately. The only problem with that is when there are multiple printers and you only want to pair with a specific one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ideally, yes... the plugin should encapsulate all of the steps to provision a printer. that's why it's possible to send USB commands. for example, to set the printer's network settings. i'd like to support the same sort of functionality for bluetooth printing too, if possible. however, that would mean that it should be done similarly on the IOS side too... and that may be problematic. i think CoreBluetooth should do what we need, on the IOS side, to get a list of printers and enumerate the services, pair, etc? here's a nice wrapper for it: https://github.com/LGBluetooth/LGBluetooth but i'm not 100% sure if it's possible to pair with "legacy" bluetooth devices programmatically on IOS. are these printers using BLE? if so, wonderful, if not... damnit!
well, we don't need a UI, necessarily. this is just a cordova plugin. it's exposing an api to app developers to do with as they please. we can provide an example implementation with a UI for test or example purposes, but that's ultimately a burden that falls on the end user of the plugin, to implement as needed, for their specific purposes. ideally we just spit back a list of compatible printers, and then the implementor can show that list to a user and let them pick the one they want, or their app code can pick one automatically based on whatever criteria they want. that's outside the scope of this plugin, i think. there should be no UI here, just API. this sort of workflow is already there for network printing. you ask for a list of printers, then pick one. ideally we can do this on both android and ios for bluetooth printing as well. but, i do understand if it's not possible on IOS. i'm sure there are "ways" such as using private frameworks, and for enterprise usage, that's fine, but you can't use private frameworks if you're pushing to the app store. for my particular use cases, app store compatibility is irrelevant, but i don't know about everyone else. that being said... PrivateFrameworks.BluetoothManager has the following methods: maybe we can add a config.xml flag to include those methods into the ios side of the plugin, optionally, depending whether they want to fully automate, with the caveat that it's only for enterprise or private use, not for deploying to the app store. thoughts? |
||
private void findNetworkPrinters(final CallbackContext callbackctx) { | ||
cordova.getThreadPool().execute(new Runnable() { | ||
public void run() { | ||
|
@@ -342,7 +363,7 @@ private void setPrinter(JSONArray args, final CallbackContext callbackctx) { | |
callbackctx.sendPluginResult(result); | ||
} catch (JSONException e) { | ||
e.printStackTrace(); | ||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, "An error occurred while trying to set the printer."); | ||
PluginResult result = pluginErrorResult("setPrinter", 2, "an error occurred while trying to set the printer: " + e.getLocalizedMessage()); | ||
callbackctx.sendPluginResult(result); | ||
} | ||
} | ||
|
@@ -365,15 +386,15 @@ private void printViaSDK(final JSONArray args, final CallbackContext callbackctx | |
|
||
String port = sharedPreferences.getString("port", ""); | ||
if ("".equals(port)) { | ||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, "No printer has been set."); | ||
PluginResult result = pluginErrorResult("printViaSDK", 4, "no printer has been set."); | ||
callbackctx.sendPluginResult(result); | ||
return; | ||
} | ||
|
||
if (PrinterInfo.Port.BLUETOOTH.toString().equals(port)) { | ||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); | ||
if (bluetoothAdapter == null) { | ||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, "This device does not have a bluetooth adapter."); | ||
PluginResult result = pluginErrorResult("printViaSDK", 3, "this device does not have a bluetooth adapter."); | ||
callbackctx.sendPluginResult(result); | ||
return; | ||
} | ||
|
@@ -394,13 +415,13 @@ private void printViaSDK(final JSONArray args, final CallbackContext callbackctx | |
bitmap = bmpFromBase64(encodedImg); | ||
} catch (JSONException e) { | ||
e.printStackTrace(); | ||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, "An error occurred while trying to retrieve the image passed in."); | ||
PluginResult result = pluginErrorResult("printViaSDK", 1, "an error occurred while trying to retrieve the image passed in: " + e.getLocalizedMessage()); | ||
callbackctx.sendPluginResult(result); | ||
return; | ||
} | ||
|
||
if (bitmap == null) { | ||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, "The passed in data did not seem to be a decodable image. Please ensure it is a base64 encoded string of a supported Android format"); | ||
PluginResult result = pluginErrorResult("printViaSDK", 1, "the passed in data did not seemd to be a decoable image. Please ensure it is a base64 encoded stirng of a supported Android format."); | ||
callbackctx.sendPluginResult(result); | ||
return; | ||
} | ||
|
@@ -514,4 +535,17 @@ public void onReceive(Context context, Intent intent) { | |
}); | ||
} | ||
|
||
private PluginResult pluginErrorResult(String namespace, int code, String message) { | ||
JSONObject result = new JSONObject(); | ||
try { | ||
result.put("namespace", namespace); | ||
result.put("code", code); | ||
result.put("message", message); | ||
} catch (JSONException e) { | ||
Log.d(TAG, "unable to encode error as json object: ", e); | ||
} | ||
|
||
return new PluginResult(PluginResult.Status.ERROR, result); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -213,7 +213,7 @@ public void handleMessage(Message msg) { | |
break; | ||
} | ||
|
||
final PluginResult cancelResult = new PluginResult(PluginResult.Status.ERROR, "Cancelled"); | ||
final PluginResult cancelResult = pluginErrorResult("printCancelled", 1, "cancelled."); | ||
mCallback.sendPluginResult(cancelResult); | ||
mCallback = null; | ||
break; | ||
|
@@ -222,7 +222,7 @@ public void handleMessage(Message msg) { | |
break; | ||
} | ||
|
||
final PluginResult wrongOSResult = new PluginResult(PluginResult.Status.ERROR, "Android OS is not supported"); | ||
final PluginResult wrongOSResult = pluginErrorResult("wrongOS", 1, "Android OS is not supported"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this mean the android version is not supported? obviously android operating system is supported, haha There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this error is that a specific version of the |
||
mCallback.sendPluginResult(wrongOSResult); | ||
mCallback = null; | ||
break; | ||
|
@@ -231,12 +231,25 @@ public void handleMessage(Message msg) { | |
break; | ||
} | ||
|
||
final PluginResult noUSBResult = new PluginResult(PluginResult.Status.ERROR, "USB device is not found"); | ||
final PluginResult noUSBResult = pluginErrorResult("noUSB", 1, "USB device is not found."); | ||
mCallback.sendPluginResult(noUSBResult); | ||
mCallback = null; | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
private PluginResult pluginErrorResult(String namespace, int code, String message) { | ||
JSONObject result = new JSONObject(); | ||
try { | ||
result.put("namespace", namespace); | ||
result.put("code", code); | ||
result.put("message", message); | ||
} catch (JSONException e) { | ||
Log.d(TAG, "unable to encode error as json object: ", e); | ||
} | ||
|
||
return new PluginResult(PluginResult.Status.ERROR, result); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What version is bundled for IOS?
Also, do we know if v3.0.4 is the current bundled version for Android? I'm guessing that's out of date...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did see that the
Android
SDK
was updated not too long ago... but theiOS
SDK
hasn't been changed since May I think?The current
SDK
version foriOS
is3.1.1
The current
SDK
version forAndroid
is3.0.7
I have not updated these binaries though. At least, I don't think I did.