How to use the retrieveConnected method? - codenameone

I'd like to know how to use the retrieveConnected() method from the Bluetooth class please. This class is part of the CN1Bluetooth.cn1lib.
I don't know how to get the paired devices with this method.
Unfortunately, there are no examples about the using of this method.
EDIT:
I used retrieveConnected() as you told me to do:
Button retco = new Button("Retrieve");
this.add(retco);
retco.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
try {
debug("Action performed 1: "+ev);
debug("Bt: "+bt);
ArrayList ar = new ArrayList();
//ar.add("180D");
debug("array: "+ar);
bt.retrieveConnected(
new ActionListener() {
public void actionPerformed(ActionEvent ev) {
debug("actionPerformed : " + ev);
main.add(new SpanLabel("TEST 3"));
debug("ev.getSource() = " + ev.getSource());
JSONObject res = (JSONObject)ev.getSource();
debug("RES = " + res);
try {
updateUI(res);
} catch (JSONException e) {
// TODO Auto-generated catch block
debug(e.getMessage());
}
};
},ar);
} catch (IOException e) {
// TODO Auto-generated catch block
debug(e.getMessage());
}
}
});
private void updateUI(JSONObject obj) throws JSONException {
this.add(new SpanLabel(obj.toString()));
this.add(new SpanLabel("TEST"));
this.revalidate();
}
But i have those error messages
ca.weblite.codename1.json.JSONException: A JSONObject text must begin with '{' at character 1 of []
at ca.weblite.codename1.json.JSONTokener.syntaxError(JSONTokener.java:448)
at ca.weblite.codename1.json.JSONObject.<init>(JSONObject.java:176)
at ca.weblite.codename1.json.JSONObject.<init>(JSONObject.java:253)
atcom.codename1.cordova.CordovaCallbackManager.sendResult(CordovaCallbackManager.java:50)
at com.codename1.cordova.CallbackContext.sendPluginResult(CallbackContext.java:26)
at com.codename1.bluetoothle.BluetoothLePlugin.retrieveConnectedAction(BluetoothLePlugin.java:1212)
at com.codename1.bluetoothle.BluetoothLePlugin.execute(BluetoothLePlugin.java:306)
at com.codename1.cordova.CordovaPlugin.execute(CordovaPlugin.java:34)
at com.codename1.cordova.CordovaNativeImpl.execute(CordovaNativeImpl.java:14)
at com.codename1.cordova.CordovaNativeStub.execute(CordovaNativeStub.java:9)
at com.codename1.cordova.Cordova.execute(Cordova.java:29)
at com.codename1.bluetoothle.Bluetooth.retrieveConnected(Bluetooth.java:129)
at be.ssii.app.forms.EidReader$3.actionPerformed(Unknown Source:97)
at com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:349)
at com.codename1.ui.Button.fireActionEvent(Button.java:570)
at com.codename1.ui.Button.released(Button.java:604)
at com.codename1.ui.Button.pointerReleased(Button.java:708)
at com.codename1.ui.Form.pointerReleased(Form.java:3369)
at com.codename1.ui.Component.pointerReleased(Component.java:4552)
at com.codename1.ui.Display.handleEvent(Display.java:2180)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1152)
at com.codename1.ui.Display.mainEDTLoop(Display.java:1070)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread$1.run(CodenameOneThread.java:60)
at java.lang.Thread.run(Thread.java:764)
There is one device paired to the device which use the app but it doesn't detect the paired one. It should work, the paired device is a BLE device.

The method retrieved paired Bluetooth LE devices. In iOS, devices that are "paired" to will not return during a normal scan. Callback is "instant" compared to a scan. UUID filtering might not work on Android, so it returns all paired BLE devices.
bluetoothle.retrieveConnected(e -> { }, params);
The params value is an array of service IDs to filter the retrieval by. If no service IDs are specified, no devices will be returned.
E.g.
ArrayList a = new ArrayList();
a.add("180D");
a.add("180F");
On success you should get an array of device objects as a result.
However looking at the code here: https://github.com/chen-fishbein/bluetoothle-codenameone/blob/master/CN1Bluethooth/src/com/codename1/bluetoothle/Bluetooth.java#L135
It looks like this line is wrong and should be changed from this:
plugin.execute("retrieveConnected", j.toString(), callack);
To this:
plugin.execute("retrieveConnected", callack, callack, j.toString());
But I haven't tested this.

Related

Reading Hadoop sequence file in Flink

How to read Hadoop sequence file in Flink? I hit multiple issues with the approach below.
I have:
DataSource<String> source = env.readFile(new SequenceFileInputFormat(config), filePath);
and
public static class SequenceFileInputFormat extends FileInputFormat<String> {
...
#Override
public void setFilePath(String filePath) {
org.apache.hadoop.conf.Configuration config = HadoopUtils.getHadoopConfiguration(configuration);
logger.info("Initializing:"+filePath);
org.apache.hadoop.fs.Path hadoopPath = new org.apache.hadoop.fs.Path(filePath);
try {
reader = new SequenceFile.Reader(hadoopPath.getFileSystem(config), hadoopPath, config);
key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), config);
value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), config);
} catch (IOException e) {
logger.error("sequence file creation failed.", e);
}
}
}
One of the issues: Could not read the user code wrapper: SequenceFileInputFormat.
Once you get an InputFormat, you can call ExecutionEnvironment.createInput(<input format>) to create your DataSource.
For SequenceFiles, the type of the data is always Tuple2<key, value>, so you have to use a map function to convert to whatever type you're trying to read.
I use this code to read a SequenceFile that contains Cascading Tuples...
Job job = Job.getInstance();
FileInputFormat.addInputPath(job, new Path(directory));
env.createInput(HadoopInputs.createHadoopInput(new SequenceFileInputFormat<Tuple, Tuple>(), Tuple.class, Tuple.class, job);

Crash on iOS when downloading and inserting in Database

I have a problem with my application on iOS only (iPad 9.7" 11.3.1), it works perfectly on the simulator and on Android device.
When the app is launched for the first time, the user has to log in. This works fine. After that, the menu form is launched and a Dialog is shown on onShowCompleted():
if (!Preferences.get("download", false)) {
dialog = new Dialog("...");
dialog.setLayout(new BorderLayout());
SpanLabel label = new SpanLabel("...");
dialog.addComponent(BorderLayout.CENTER, label);
dialog.show(Display.getInstance().getDisplayHeight() / 5, ..., ..., ...);
}
In the constructor, a method that downloads informations is launched :
if (!Preferences.get("download", false)) {
dlReferentiel();
}
The method :
public void dlReferentiel() {
source = DataSource.getInstance();
// I also tried with invokeAndBlock() but doesn't work
/*
Display.getInstance().invokeAndBlock(() -> requestS());
Display.getInstance().invokeAndBlock(() -> requestB());
Display.getInstance().invokeAndBlock(() -> requestZ());
Display.getInstance().invokeAndBlock(() -> requestA());
*/
requestS();
requestB();
requestZ();
requestA();
}
The requestX methods get informations from server with ConnectionRequest :
(Exemple with requestA() which needs to be the last because it disposes the dialog, it is the only one that calls the UI)
public void requestA() {
ConnectionRequest connectionRequest = new ConnectionRequest() {
ArrayList<A> as = new ArrayList<>();
#Override
protected void readResponse(InputStream in) throws IOException {
JSONParser json = new JSONParser();
Reader reader = new InputStreamReader(in, "UTF-8");
Map<String, Object> data = json.parseJSON(reader);
for (String s : data.keySet()) {
as.add(new A(s, (String) data.get(s)));
}
}
#Override
protected void postResponse() {
source.createAllA(as); // makes insertions with Transaction
ToastBar.showErrorMessage("Référentiel téléchargé", 10);
dialog.dispose();
Preferences.set("download", true);
}
};
connectionRequest.setUrl(URL_A);
connectionRequest.setPost(true);
NetworkManager.getInstance().addToQueue(connectionRequest);
}
I was able to see some logs with a Mac. Each time, the app crashes after the Dialog is shown and few insertions are made. The same error message is output :
HW kbd: Failed to set (null) as keyboard focus
Unable to get short BSD proc info for 513: No such process
Unable to get proc info for 513: Undefined error: 0
I search for informations about this issue but nothing interesting with Codename One.
I don't know what to do with this error, I tried some things like using invokeAndBlock() or changing build hints like ios.keyboardOpen (just because there is "keyboard" in it) but nothing worked.
Thanks for the help.

Parse method of BasicDexFileReader

I would like to know if I can use the parse method of BasicDexFileReader to load a dexfile which is decrypted into a byte array?
public void parse(byte[] dexBytes) throws IllegalArgumentException, IOException/*,
RefNotFoundException */ {
// Get a DalvikValueReader on the input stream.
reader = new DalvikValueReader(dexBytes, FILE_SIZE_OFFSET);
readHeader();
readStrings();
readTypes();
}
I would be glad if someone can explain what exactly is the purpose of parse method and can it be used in a way i have asked.
Thanks
Take a look at DexMaker.java, which needs to solve this problem for generating code rather than decrypting it.
Here's the relevant sample:
byte[] dex = ...;
/*
* This implementation currently dumps the dex to the filesystem. It
* jars the emitted .dex for the benefit of Gingerbread and earlier
* devices, which can't load .dex files directly.
*
* TODO: load the dex from memory where supported.
*/
File result = File.createTempFile("Generated", ".jar", dexCache);
result.deleteOnExit();
JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result));
jarOut.putNextEntry(new JarEntry(DexFormat.DEX_IN_JAR_NAME));
jarOut.write(dex);
jarOut.closeEntry();
jarOut.close();
try {
return (ClassLoader) Class.forName("dalvik.system.DexClassLoader")
.getConstructor(String.class, String.class, String.class, ClassLoader.class)
.newInstance(result.getPath(), dexCache.getAbsolutePath(), null, parent);
} catch (ClassNotFoundException e) {
throw new UnsupportedOperationException("load() requires a Dalvik VM", e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getCause());
} catch (InstantiationException e) {
throw new AssertionError();
} catch (NoSuchMethodException e) {
throw new AssertionError();
} catch (IllegalAccessException e) {
throw new AssertionError();
}

ChannelFactory method call increse memory

I have an winform application which consumes windows service, i user ChannelFactory
to connect to service, problem is when i call service method using channel the memory usage increase and after
method execute memory not go down(even after form close), i call GC.Collect but no change
channel Create class
public class Channel1
{
List<ChannelFactory> chanelList = new List<ChannelFactory>();
ISales salesObj;
public ISales Sales
{
get
{
if (salesObj == null)
{
ChannelFactory<ISales> saleschannel = new ChannelFactory<ISales>("SalesEndPoint");
chanelList.Add(saleschannel);
salesObj = saleschannel.CreateChannel();
}
return salesObj;
}
}
public void CloseAllChannels()
{
foreach (ChannelFactory chFac in chanelList)
{
chFac.Abort();
((IDisposable)chFac).Dispose();
}
salesObj = null;
}
}
base class
public class Base:Form
{
public Channel1 channelService = new Channel1();
public Channel1 CHANNEL
{
get
{
return channelService;
}
}
}
winform class
Form1:Base
private void btnView_Click(object sender, EventArgs e)
{
DataTable _dt = new DataTable();
try
{
gvAccounts.AutoGenerateColumns = false;
_dt = CHANNEL.Sales.GetDatatable();
gvAccounts.DataSource = _dt;
}
catch (Exception ex)
{
MessageBox.Show("Error Occurred while processing...\n" + ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
CHANNEL.CloseAllChannels();
_dt.Dispose();
//GC.Collect();
}
}
You're on the right track in terms of using ChannelFactory<T>, but your implementation is a bit off.
ChannelFactory<T> creates a factory for generating channels of type T. This is a relatively expensive operation (as compared to just creating a channel from the existing factory), and is generally done once per life of the application (usually at start). You can then use that factory instance to create as many channels as your application needs.
Generally, once I've created the factory and cached it, when I need to make a call to the service I get a channel from the factory, make the call, and then close/abort the channel.
Using your posted code as a starting point, I would do something like this:
public class Channel1
{
ChannelFactory<ISales> salesChannel;
public ISales Sales
{
get
{
if (salesChannel == null)
{
salesChannel = new ChannelFactory<ISales>("SalesEndPoint");
}
return salesChannel.CreateChannel();
}
}
}
Note that I've replaced the salesObj with salesChannel (the factory). This will create the factory the first time it's called, and create a new channel from the factory every time.
Unless you have a particular requirement to do so, I wouldn't keep track of the different channels, especially if follow the open/do method/close approach.
In your form, it'd look something like this:
private void btnView_Click(object sender, EventArgs e)
{
DataTable _dt = new DataTable();
try
{
gvAccounts.AutoGenerateColumns = false;
ISales client = CHANNEL.Sales
_dt = client.GetDatatable();
gvAccounts.DataSource = _dt;
((ICommunicationObject)client).Close();
}
catch (Exception ex)
{
((ICommunicationObject)client).Abort();
MessageBox.Show("Error Occurred while processing...\n" + ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
The code above gets a new ISales channel from the factory in CHANNEL, executes the call, and then closes the channel. If an exception happens, the channel is aborted in the catch block.
I would avoid using Dispose() out of the box on the channels, as the implementation in the framework is flawed and will throw an error if the channel is in a faulted state. If you really want to use Dispose() and force the garbage collection, you can - but you'll have to work around the WCF dispose issue. Google will give you a number of workarounds (google WCF Using for a start).

How to get from a WebElement the Findby type and string

How can I get the Findby type and string from a WebElement?
I am using a self-built webDriverWait function that will be able to receive By Or Webelement to be used at the presenceOfElementLocated() function.
Defining the WebElement
#FindBy(xpath = "//div[#id='calendar-1234']")
private WebElement calander;
The Two webDriverWaitFor Functions
The first uses By and is working okay: , and the second uses webElement
public void webDriverWaitFor(WebDriver driver, By by) throws ElementLocatorException {
try{
(new WebDriverWait(driver, 5))
.until(ExpectedConditions.presenceOfElementLocated( by ));
}
catch (Exception e) {
throw new ElementLocatorException(by);
}
}
The second uses WebElement and I am trying to get the By type and string.
this implimintation is not good: By.id(webElement.getAttribute("id"))
public void webDriverWaitFor(WebDriver driver, WebElement webElement) throws ElementLocatorException {
try{
(new WebDriverWait(driver, 5))
.until(ExpectedConditions.presenceOfElementLocated( By.id(webElement.getAttribute("id")) ));
}
catch (Exception e) {
throw new ElementLocatorException( By.id(webElement.getAttribute("id")) );
}
}
how will I be able to implement the following?
webDriverWaitFor(driver, calander);
Usually you could call element.toString() and parse it. The string that is being returned contains all the necessary information.
But it's not going to work in your case as this information can be obtained only after the WebElement has been instantiated. You are using #FindBy tag which means that the element will be looked up at the moment you will try to use it. Your example does not work because the moment you are trying to call webElement.getAttribute the driver.findBy is internally called and it fails since the element does not yet exists.
The only solution I can think of is to write your own wait method
public boolean isElementPresent(WebElement element) {
try {
element.isDisplayed(); // we need to call any method on the element in order to force Selenium to look it up
return true;
} catch (Exception e) {
return false;
}
}
public void webDriverWaitFor(WebElement element) {
for (int second = 0; ; second++) {
if (second >= 60) {
//element not found, log the error
break;
}
if (isElementPresent(element)) {
//ok, we found the element
break;
}
Thread.sleep(1000);
}
}
This example will not work well however if you are using implicit waits (each try to call element.isDisplayed would take a lot of time)!

Resources