CodeSacnner library of cn1 works in Android but crashed in ios without any error message - codenameone

I use the CodeScanner library of cn1 for QR code scan. This library installs Barcode Scanner + simple for the scanning process and works in Android.
I also build my project for ios. But my program crashes in my iPhone 7 max without any error message when trying to scan QRCode. The library doesn't install any 3rd party for the scanning process in iOS.
CodeScanner.getInstance().scanQRCode(new ScanResult() {
public void scanCompleted(String contents, String formatName, byte[] rawBytes) {
}
public void scanCanceled() {
}
public void scanError(int errorCode, String message) {
}
});

Try adding the build hint: ios.NSCameraUsageDescription with description of why you need to use the camera.
This should have been added automatically by the simulator and should have been documented. I suggest opening an issue on that here.

Related

Using Shiny with UNO Platform

Looking for a way to use shinyorg/shiny nuget packages in cross-platform projects built on the UNO platform.
Facing some challenges beyond my (limited) skills for iOS development, I'm specifically looking for how to integrate Shiny.Core into the solution iOS project.
More precisely, I'm looking for where to put this initialization override:
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);
Since when I try adding this in the Main.cs (Application class) of the iOS project, I can't find where to start...
The Main.cs class from the iOS project contains a static Main method (which is the main entry point of the app) in which a call to UIApplication.Main(args, null, typeof(App)); is made.
UIApplication being in fact UIKit.UIApplication
Following this guide https://github.com/shinyorg/shiny/tree/master/src/Shiny.Core where it's said:
* Add the following as the first line in your AppDelegate.cs - FinishedLaunching method
using Shiny;
this.ShinyFinishedLaunching(new YourStartup());
** IOS JOBS **
If you plan to use jobs in iOS, please do the following:
1. Add this to your AppDelegate.cs
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);
On iOS, the AppDelegate is actually the App class in your app, created from the default Uno Platform templates.
Windows.UI.Xaml.Application inherits from UIApplicationDelegate and provides a way declare this:
#if __IOS__
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);
#endif
in order for the code for the other platforms to ignore this iOS-specific code

Playing regular and looping sounds with JDK 11?

I am using Java JDK 11.0.8 ("Installed JREs" under Eclipse is set to jdk-11.0.8), Eclipse 2020-06, and Codename One 6.0.0.
I have recently switched from JDK 8 to JDK 11 and noticed that playing sounds option in my app does not work anymore...
Note that I uncheck "Java 8" when I create my app and I am only trying to work things out in the simulator (I am not trying to deploy the app to an actual mobile device).
I want to play a "regular sound" (I want to play a sound from beginning to end, and when it ends I do not need to replay it from the beginning) and also a "looping sound" (the sound should come to its beginning when it ends and hence, I can continuously play it in the background).
Hence I have two questions:
Question1 - About "regular sounds"
I would like to create Media object just once and then re-use it whenever I need to play the same regular sound.
For that purpose I am encapsulating a Media creation inside a class as follows:
public class RegularSound {
private Media m;
public RegularSound(String fileName) {
try{
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/"+fileName);
m = MediaManager.createMedia(is, "audio/wav");
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void play() {
m.setTime(0);
m.play();
}
}
Then I instantiate the RegularSound object and play it as follows:
mySound = new RegularSound("example.wav");
mySound.play();
Please note that example.wav is copied directly under the "src" directory of my project.
This code used to work with JDK 8, but with JDK 11, I get the following build errors:
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: javax/media/ControllerListener
at com.codename1.impl.javase.JavaJMFSEPort$1.run(JavaJMFSEPort.java:67)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.lang.ClassNotFoundException: javax.media.ControllerListener
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.ClassLoader.findSystemClass(ClassLoader.java:1247)
at com.codename1.impl.javase.ClassPathLoader.findClass(ClassPathLoader.java:269)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at com.codename1.impl.javase.ClassPathLoader.loadClass(ClassPathLoader.java:115)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at com.codename1.impl.javase.ClassPathLoader.loadClass(ClassPathLoader.java:107)
... 14 more
Question2- About "looping sounds"
For looping sound I have created another class as follows:
public class LoopingSound implements Runnable{
private Media m;
String fileName;
public LoopingSound(String fileName){
try{
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/"+fileName);
m = MediaManager.createMedia(is, "audio/wav",this);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void pause()
{
m.pause();
}
public void play()
{
m.play();
}
public void run() {
m.setTime(0);
m.play();
}
}
But I again get build errors when I instantiate an object of LoopingSound and try to play it...
So could you please let me know how to change code for regular and looping sounds so that I do not receive above-mentioned errors when using JDK 11?
UPDATE
Thanks for the reply #shai-almog. I have installed CEF. But I am receiving some messages on the console in runtime and I can't hear the sound playing... I run the following code:
try {
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/example.wav");
Media m = MediaManager.createMedia(is, "audio/wav");
m.play();
} catch (IOException e) {
e.printStackTrace();
}
and I receive the following messages on console when I run this code (it throws an exception at the end):
Adding CEF to classpath
Retina Scale: 2.0
CEF Args: [--disable-gpu, --disable-software-rasterizer, --disable-gpu-compositing, --touch-events=enabled, --enable-media-stream, --device-scale-factor=4, --force-device-scale-factor=4, --autoplay-policy=no-user-gesture-required, --enable-usermedia-screen-capturing]
Using:
JCEF Version = 83.4.0.260
CEF Version = 83.4.0
Chromium Version = 83.0.4103.106
AppHandler.stateHasChanged: INITIALIZING
initialize on Thread[AWT-EventQueue-0,6,main] with library path C:\Users\pmuyan\.codenameone\cef\lib\win64
Added scheme search://
Added scheme client://
Added scheme cn1stream://
DevTools listening on ws://127.0.0.1:8088/devtools/browser/591d3502-6fd6-4997-9131-9a2a352e47b1
AppHandler.stateHasChanged: INITIALIZED
Running ready callbacks
Exception in thread "AWT-EventQueue-0" Address changed to data:text/html,%3C!doctype%20html%3E%3Chtml%3E%3Chead%3E%3Cstyle%20type%3D'text%2Fcss'%3Edocument%2C%20body%20%7Bpadding%3A0%3Bmargin%3A0%3B%20width%3A100%25%3B%20height%3A%20100%25%7D%20video%2C%20audio%20%7Bmargin%3A0%3B%20padding%3A0%3B%20width%3A100%25%3B%20height%3A%20100%25%7D%3C%2Fstyle%3E%3C%2Fhead%3E%3Cbody%3E%3Caudio%20id%3D'cn1Media'%20width%3D'640'%20height%3D'480'%20style%3D'width%3A100%25%3Bheight%3A100%25'%20src%3D'https%3A%2F%2Fcn1app%2Fstreams%2F1'%2F%3E%3Cscript%3Ewindow.cn1Media%20%3D%20document.getElementById('cn1Media')%3Bfunction%20callback(data)%7B%20cefQuery(%7Brequest%3A'shouldNavigate%3A'%2BJSON.stringify(data)%2C%20onSuccess%3A%20function(response)%7B%7D%2C%20onFailure%3Afunction(error_code%2C%20error_message)%20%7B%20console.log(error_message)%7D%7D)%3B%7Dcn1Media.addEventListener('pause'%2C%20function()%7B%20callback(%7B'state'%3A'paused'%7D)%7D)%3Bcn1Media.addEventListener('play'%2C%20function()%7B%20callback(%7B'state'%3A'playing'%7D)%7D)%3Bcn1Media.addEventListener('ended'%2C%20function()%7B%20callback(%7B'state'%3A'ended'%7D)%7D)%3Bcn1Media.addEventListener('durationchange'%2C%20function()%7B%20callback(%7B'duration'%3A%20Math.floor(cn1Media.duration%20*%201000)%7D)%7D)%3Bcn1Media.addEventListener('timeupdate'%2C%20function()%7B%20callback(%7B'time'%3A%20Math.floor(cn1Media.currentTime%20*%201000)%7D)%7D)%3Bcn1Media.addEventListener('volumechange'%2C%20function()%7B%20callback(%7B'volume'%3A%20Math.round(cn1Media.volume%20*%20100)%7D)%7D)%3Bcn1Media.addEventListener('error'%2C%20function()%7B%20var%20msg%20%3D%20'Unknown%20Error'%3B%20try%20%7Bmsg%20%3D%20cn1Media.error.message%20%2B%20'.%20Code%3D'%2Bcn1Media.error.code%3B%7Dcatch(e)%7B%7D%20callback(%7B'error'%3A%20msg%7D)%7D)%3B%3C%2Fscript%3E%20%3C%2Fbody%3E%3C%2Fhtml%3E
UPDATE 2
I could manually add Open JavaFX 11 to Eclipse and to Codename One app running under Eclipse while using JDK 11 as follows:
Step1) Create JavaFX11 user library under Eclipse
Download JavaFX 11 from https://gluonhq.com/products/javafx/
unzip it -> creates javafx-sdk-11.0.2 folder
Create a User Library: Eclipse -> Window -> Preferences -> Java -> Build Path -> User Libraries -> New.
Name it JavaFX11.
Hit "Add External JARs" and include all the jars under javafx-sdk-11.0.2\lib
Step 2) Add the JavaFX11 library to the project:
Right click on project.
Select Build path -> Configure Build Path
Goto Library tab->Add Library->User Library->Check JavaFX11->Apply and Close
Now, I can hear sounds playing in my Codename One application.
However, I need to run my application from command prompt and regular command line to run the apps does not work anymore (the app cannot find the JavaFX related classes from the command prompt and I get the same errors listed above). So could you please tell me how to modify the command line so that Codename One project that uses JavaFX would run from command prompt?
Here is the regular command line I use:
java -cp dist\Proj.jar;JavaSE.jar com.codename1.impl.javase.Simulator com.mycompany.hi.Main
BTW, I have tried to add javafx.media.jar under javafx-sdk-11.0.2\lib to the classpath (-cp) in the command line, but this did not work...
UPDATE 3
We have solved the issue by using the following command line:
java --module-path C:\javafx-sdk-11.0.2\lib\ --add-modules= ALL-MODULE-PATH -cp dist\Proj.jar;JavaSE.jar com.codename1.impl.javase.Simulator com.mycompany.hi.Main
(where C:\javafx-sdk-11.0.2\lib\ is our )
Thanks!
The TL;DR
Either install CEF as explained here or switch to ZuluFX 11 for your VM.
The explanation:
This used to work until we integrated CEF support we would download JavaFX dynamically for JDK 11 installs but this caused a lot of related problems. So we decided to migrate to CEF, this is still in progress and while it's ongoing JavaFX dynamic download is broken. Once it's done CEF will be auto-installed and this will be seamless again.
This impacts browser component and media which are the two components implemented by JavaFX.

Codename One Full Screen Google Ad not loading

I have an Android app that I want to use with full screen Google ads.
I have got the small ad running, but the full screen ad does show any content.
The information I found on the internet is a little conflicting.
This link here https://github.com/chen-fishbein/admobfullscreen-codenameone advises to add several build hints to the project, but then it refuses to build.
The other one here https://github.com/shannah/admobfullscreen-codenameone does not mention any build hints, but then the ads won't load.
The answer here unable to build codename one app after adding admobfullscreen lib tells to ignore the includeGplayServices hint.
I have build the project with the sample code, but to no avail.
What would be the correct approach?
Edit : code added
String idTest = "ca-app-pub-3940256099942544/6300978111";
String idReal = "ca-app-pub-3524209908223138~0000000000";
admobTestId = new AdMobManager(idTest);
admobRealId = new AdMobManager(idReal);
f.addComponent(new Button(new Command("admob test load and show"){
public void actionPerformed(ActionEvent evt) {
admobTestId.loadAndShow();
}
}));
f.addComponent(new Button(new Command(" admob real load & show"){
public void actionPerformed(ActionEvent evt) {
admobRealId.loadAndShow();
}
}));

A webBrowser form crashes the app when backed

When I press back button to go from a form with webBrowser component to any other form, it crashes in android. However, it works fine in iOS. Specifically it doesnt work in android samsung galaxy s5(android version 5.0) but works great in simulator and other android devices as well. I am updating the app. It worked great in previously built versions but is giving problem in new builds. I haven't changed anything in the form which makes it crash though.
I tried to debug the device and got following log. I think "Fatal signal 11 (SIGSEGV), code 1" is the main issue here
Log:
11-15 14:40:51.278: A/google-breakpad(9135): M A0598000 008F1000 007A1000 000000000000000000000000000000000 data#app#com.capitalEye.roundTable-1#base.apk#classes.dex
11-15 14:40:51.453: A/libc(8864): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 8864 (lEye.roundTable)
11-15 14:40:53.653: E/audit(5364): type=1701 msg=audit(1479200153.653:335994): auid=4294967295 uid=10217 gid=10217 ses=4294967295 subj=u:r:untrusted_app:s0 pid=8864 comm="lEye.roundTable" reason="memory violation" sig=11
My code:
protected void beforeWebView(Form f) {
f.setLayout(new BorderLayout());
f.getToolbar().setUIID("Container");
t = new Toolbar();
t.setUIID("TitleAreaa");
f.setToolBar(t);
Style s = UIManager.getInstance().getComponentStyle("Button");
Image backtoRTN = FontImage.createMaterial(FontImage.MATERIAL_ARROW_BACK, s);
back = new Command("Back to RTN", backtoRTN) {
#Override
public void actionPerformed(ActionEvent evt) {
showForm("BusinessForum", this);
}
};
back.putClientProperty("uiid", "BacktoRTN");
f.setBackCommand(back);
t.addCommandToLeftBar(back);
}
#Override
protected void postWebView(Form f) {
if (Connectivity.isConnected()) {
WebBrowser wb = new WebBrowser();
if (businessWebsiteUrl != null && !businessWebsiteUrl.equals("")) {
wb.setURL("http://" + businessWebsiteUrl);
f.add(BorderLayout.CENTER, wb);
f.revalidate();
}
}
}
That's a system crash from the browser component which is a native peer. I'm guessing the underlying HTML triggered a bug in the webkit code of the native OS triggering that crash.
Since we use the native Android OS browser and VM a system level crash is an Android bug. We can workaround some of those but if it's within the HTML the likelihood of a workaround is slim.

Tabris, Eclipse RAP: Is there a public API to get to know which client has requested the page?

I am writing a RAP application using Eclipse RAP. The client may be any brower, an iPad or an android tablet (using Tabris). Is there any chance to find out which client has sent a request?
The background for my question is: Tabris does not support SashForms until now. For this reason, I want to render a SashFrom in case I am serving a web client but don't want to create a SashForm if serving the android client. I could do something like this:
public static boolean isAndroid() {
return getUserAgent().contains(Constants.ID_ANDROID);
}
private static String getUserAgent() {
return RWT.getRequest().getHeader(Constants.USER_AGENT);
}
public static boolean isIos() {
return getUserAgent().contains(Constants.ID_IOS);
}
public static boolean isWeb() {
return !isAndroid() && !isIos();
}
But I'd like to avoid this approach, because it uses internal API and since I am using standalone RAP I need to add a the servlet-api.jar to WEB-INF/lib folder to get this running, which is also not very nice.
Thanks in advance for your help and information,
Tobias.
I think this can help: https://github.com/eclipsesource/tabris/blob/master/com.eclipsesource.tabris/src/com/eclipsesource/tabris/ClientDevice.java
One alternative approach instead of using ClientDevice is to use RWT.getClient().
if( RWT.getClient() instanceof WebClient ) {
....
}
This is sometimes useful because ClientDevice can be null if the web client accesses the application. It's a client service that is only valid for the mobile client atm.

Resources