I am using Native Android Code called from Codenameone. I am discovering bluetooth devices, connecting to them and so on. However I have made use of local variables like bluetoothDevices to set return values from these activities that are called by StateMachine. The code works fine, but I would like to replace them by callback methods. How do I go about this?
PrinterNativeCallsImpl.java that does the discovery n so on.
public class PrinterNativeCallsImpl {
//#ifndef REMOVE_DEBUG
private static final Logger logger = LoggerFactory.getLogger(PrinterNativeCallsImpl.class);
//#endif
// ???? WANT TO AVOID DOING THIS
public String bluetoothDevices = "";
public String selprinter = "";
public String errorMsg = "";
private int result = 9;
public String printerInfo = "";
public void connect(String printer){
final Activity ctx = com.codename1.impl.android.AndroidNativeUtil.getActivity();
final Intent connectIntent = new Intent(ctx, BluetoothFilePrinter.class);
result = PrinterNativeCalls.PENDING;
Bundle bundle = new Bundle();
bundle.putString(BTWrapperActivity.EXTRA_DEVICE_ADDRESS, printer);
bundle.putBoolean("IS_CONNECTED", false);
bundle.putInt(BluetoothFilePrinter.REQUEST_CODE, BluetoothFilePrinter.CONNECT_REQUEST);
connectIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
connectIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
connectIntent.putExtras(bundle);
startActivityForResult(connectIntent, BluetoothFilePrinter.CONNECT_REQUEST, new IntentResultListener(){
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
data = connectIntent;
}
if (requestCode == BluetoothFilePrinter.CONNECT_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
selprinter = data.getExtras().getString(BTWrapperActivity.EXTRA_DEVICE_ADDRESS);
result = PrinterNativeCalls.OK;
} else {
result = PrinterNativeCalls.ERROR;
errorMsg = data.getExtras().getInt(BluetoothFilePrinter.ERROR)
+" - "+data.getExtras().getString(BluetoothFilePrinter.ERROR_MSG);
}
}
}
});
}
/**
* Start an intent for result
*/
public static void startActivityForResult(Intent intent, int actRequestCode, final IntentResultListener listener){
final com.codename1.impl.android.CodenameOneActivity act = (com.codename1.impl.android.CodenameOneActivity) com.codename1.impl.android.AndroidNativeUtil.getActivity();
act.startActivityForResult(intent, actRequestCode);
act.setIntentResultListener(new IntentResultListener() {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
listener.onActivityResult(requestCode, resultCode, data);
act.restoreIntentResultListener();
}
});
}
public int getResult() {
return result;
}
public String getSelprinter() {
return selprinter;
}
public String getErrorMsg(){
return errorMsg;
}
public boolean isSupported() {
return true;
}
public String getPrinterStatus() {
return printerInfo;
}
public String getBluetoothDevices() {
return bluetoothDevices;
}
public void discoverDevices(){
//showDlg();
final Activity ctx = com.codename1.impl.android.AndroidNativeUtil.getActivity();
final Intent discIntent = new Intent(ctx, BluetoothFilePrinter.class);
result = PrinterNativeCalls.PENDING;
Bundle bundle = new Bundle();
bundle.putInt(BluetoothFilePrinter.REQUEST_CODE, BluetoothFilePrinter.DISCOVER_REQUEST);
discIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
discIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
discIntent.putExtras(bundle);
startActivityForResult(discIntent, BluetoothFilePrinter.DISCOVER_REQUEST, new IntentResultListener(){
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
data = discIntent;
}
if (requestCode == BluetoothFilePrinter.DISCOVER_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
bluetoothDevices = data.getExtras().getString(BTWrapperActivity.DEVICES_DISCOVERED);
result = PrinterNativeCalls.OK;
} else {
result = PrinterNativeCalls.ERROR;
errorMsg = data.getExtras().getInt(BluetoothFilePrinter.ERROR)
+" - "+data.getExtras().getString(BluetoothFilePrinter.ERROR_MSG);
}
}
}
});
}
}
Sample Code from StateMachine that uses it:
private void discoverBTDevices(){
final PrinterNativeCalls mPrinter = (PrinterNativeCalls) NativeLookup.create(PrinterNativeCalls.class);
isPrinterMode = true;
final Dialog okDialog = (Dialog) createContainer(fetchResourceFile(), "OkDialog");
new Thread() {
public void run() {
mPrinter.discoverDevices();
while (mPrinter.getResult() == PrinterNativeCalls.PENDING) {
try {
sleep(100);
} catch (InterruptedException ex) {
// Ignore interrupted exception
}
}
int result = mPrinter.getResult();
if (result == PrinterNativeCalls.ERROR) {
String errMsg = mPrinter.getErrorMsg();
if (errMsg!=null && errMsg.length()>=3) {
addGreenRedTitle(okDialog, false, errMsg);
}else{
addGreenRedTitle(okDialog, false, "DISCOVERY did not complete due to an error. Please retry");
}
isConnected = false;
} else if (result == PrinterNativeCalls.PENDING) {
//Do nothing
} else if (result == PrinterNativeCalls.OK) {
final String devices = mPrinter.getBluetoothDevices();
devicesVect = getAllDevices(devices);
showFormInEDT("currency", null);
}
} // eof run
}.start();
}
How do I use callback to avoid mPrinter.getBluetoothDevices() kind of calls?
I suggest adding a static class within the Codename One src directory and just invoking the static methods on that class. This is pretty trivial for the Android version.
E.g. in your Codename One src directory (under the right package):
public class BTCallbacks {
public static void deviceDiscovered(String name) {
// handle this in code, keep in mind its the Android thread so make sure to use callSerially()!
}
}
Then in the native code do:
BTCallbacks.deviceDiscovered(...);
For the iOS version you will need to use the somewhat undocumented XMLVM calling convention to invoke such a static method but it should be easily doable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With