Codename One's MediaPlayer works in Simulator but on Android - codenameone

I want to have a simple form that shows a video from a public URL. So I found out the MediaPlayer controller and I copied the example from the docs
final Form hi = new Form("MediaPlayer", new BorderLayout());
hi.setToolbar(new Toolbar());
Style s = UIManager.getInstance().getComponentStyle("Title");
FontImage icon =
FontImage.createMaterial(FontImage.MATERIAL_VIDEO_LIBRARY, s);
hi.getToolbar().addCommandToRightBar(new Command("", icon) {
#Override
public void actionPerformed(ActionEvent evt) {
Display.getInstance().openGallery((e) -> {
if(e != null && e.getSource() != null) {
String file = (String)e.getSource();
try {
Media video = MediaManager.createMedia(file, true);
hi.removeAll();
hi.add(BorderLayout.CENTER, new MediaPlayer(video));
hi.revalidate();
} catch(IOException err) {
Log.e(err);
}
}
}, Display.GALLERY_VIDEO);
}
});
hi.show();
It worked flawlessly in the simulator, the button appears and when I select a video file the component appears.
But when testing it on actual Android device, after I select the video nothing happens. I wonder if I missed some configuration. I am looking for the simplest possible way to run videos on Codename One for Android.
EDIT: It looks like the event listener in Display#openGallery is not being called.

Related

trouble with Theme in the olderGUI

i´m starting with CN1, and i traying with Todo App example. When i run de app in Netbeans, only appears a blank form, I changed the themes, I added a jpg image and made others changes in the res file with the olderGUI Builder and use the function theme = UIManager.initNamedTheme("/theme","Theme 2");, but i don´t have any change in the dorm when i try to simulate in Netbeans.
This is the complete code in the TodoApp java file, I comment the part of the new hi Form (I use the "Hi World" bare bones template):
public class TodoApp {
private Form current;
private Resources theme;
public void init(Object context) {
// use two network threads instead of one
updateNetworkThreadCount(2);
//theme = UIManager.initFirstTheme("/theme");
theme = UIManager.initNamedTheme("/theme","Theme 2");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature
Log.bindCrashProtection(true);
addNetworkErrorListener(err -> {
// prevent the event from propagating
err.consume();
if(err.getError() != null) {
Log.e(err.getError());
}
Log.sendLogAsync();
Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null);
});
}
public void start() {
if(current != null){
current.show();
return;
}
//Form hi = new Form("Hi World", BoxLayout.y());
//hi.add(new Label("Hi World"));
//hi.show();
new TodoForm();
}
public void stop() {
current = getCurrentForm();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
}
I couldn't find what i do wrong. Thanks!!!
P.D. Sorry for my English, I learning it too.
We recommend avoiding the old GUI builder. It's no longer supported and wasn't designed for modern mobile apps. In order to use it you have to create a special type of project (old GUI project) and only that type of project works with it.
The new GUI builder works better, it has a more powerful layout system and works in a way that's more consistent with modern GUI builders. See https://www.codenameone.com/blog/tutorial-gui-builder-autolayout-signin-form-responsive.html

ImageViewer isnot working fine codenameone

I have a couple of questions regarding image viewer.
1)ImageViewer autoslides isnot working.The imageViewer works initially when the app is first started. But as soon as any other form is opened & then going back to the form containing imageViewer, the autoslide doesnt work.
Code for img viewer auto slide
placeholderForTable = (EncodedImage) theme.getImage("placeholderWithAnimate.png");
placeholderForTable = placeholderForTable.scaledEncoded(screenWidth, 30 + (screenWidth * 1 / 3));
BusinessForumImagesConnection bfic = new BusinessForumImagesConnection();
bfic.businessForumImagesConnectionMethod(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
DefaultListModel<Image> images;
if (bfic.response != null) {
for (Map<String, Object> entrySet : bfic.response) {
String imgUrl = (String) entrySet.get("imgUrl");
Image adImage = URLImage.createToStorage(placeholderForTable, imgUrl.substring(0, imgUrl.lastIndexOf(".")), + imgUrl, URLImage.RESIZE_SCALE);
adsSlideImagesArray.add(adImage);
}
}
ImageViewer imv = new ImageViewer();
Container adsContainer = BoxLayout.encloseY(imv);
if (adsSlideImagesArray != null) {
slideIndex = 0;
images = new DefaultListModel<>(adsSlideImagesArray);
imv.setImage(images.getItemAt(0));
imv.setImageList(images);
imv.setSwipePlaceholder(Image.createImage(100, 100));
Runnable r = new Runnable() {
public void run() {
if (slideIndex < images.getSize()) {
nextImage = (Image) images.getItemAt(slideIndex);
if (nextImage != null) {
imv.setImage(nextImage);
}
slideIndex++;
} else {
slideIndex = 0;
}
}
};
if (uITimer == null) {
uITimer = new UITimer(r);
}
if (uITimer != null) {
uITimer.schedule(5000, true, f); //5 seconds
}
}
});
2) Some random images are not always displayed in image viewer. It happens in both simulator & real devices. I have checked if the UrlImage is cached or not in storage. There are all the file saved but some of them are never displayed in image viewer.
Instead of image Viewer, i set the image icon in label and loop them. All the labels have their respective icons, but there is a problem in imageViewer. Code is same as above.
Make sure your timer fires and that no one canceled it.
Do you see the placeholder instead of the image? Details like that are essential.
Images that are deeper within the image viewer stack won't be pre-fetched. Notice that URLImage wasn't designed for the image viewer and is probably a bad idea for it as URLImage resizes the images. We recommend using a download method to get full sized images for the image viewer see this old post: https://www.codenameone.com/blog/image-viewer-from-the-web.html

Handle event for html button codename one

In form I embedded WebBrowser component with lots of html contents (Mainly Table, buttons ) for rich ui. Is it possible to handle event on clicking html button ?
Sure, look at the kitchen sink demo for a sample.
Generally just navigate to a URL on the event and implement your own BrowserNavigationCallback to handle navigation to that specific URL.
This is the code from the Kitchen Sink demo notice the setBrowserNavigationCallback block:
final WebBrowser wb = new WebBrowser();
if(wb.getInternal() instanceof BrowserComponent) {
Button btn = new Button("Add");
final TextArea content = new TextArea();
Container north = new Container(new BorderLayout());
north.addComponent(BorderLayout.CENTER, content);
north.addComponent(BorderLayout.EAST, btn);
cnt.addComponent(BorderLayout.NORTH, north);
content.setHint("Add to web document");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
((BrowserComponent)wb.getInternal()).execute("fnc('" + content.getText() + "');");
}
});
((BrowserComponent)wb.getInternal()).setBrowserNavigationCallback(new BrowserNavigationCallback() {
public boolean shouldNavigate(String url) {
if(url.startsWith("http://sayhello")) {
// warning!!! This is not on the EDT and this method MUST return immediately!
Display.getInstance().callSerially(new Runnable() {
public void run() {
((BrowserComponent)wb.getInternal()).execute("fnc('this was written by Java code!')");
}
});
return false;
}
return true;
}
});
}

How do I get Codenameone to capture video?

I am using the following code to try to capture video with codenameone 2.0
tProperty.setHint("name the property that is a media");
final CheckBox cbVideo = new CheckBox("Video");
final Button bCapture = new Button("Capture Media");
final MediaPlayer mpPlayer = new MediaPlayer();
bCapture.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ect){
try {
if (cbVideo.isSelected()) {
String value = Capture.captureVideo();
mpPlayer.setDataSource(value);
mpPlayer.setName(tProperty.getText());
}else {
String value = Capture.captureAudio();
mpPlayer.setDataSource(value);
mpPlayer.setName(tProperty.getText());
}
}catch (Exception e){
}
}
});
cM.addComponent(tProperty);
cM.addComponent(cbVideo);
cM.addComponent(bCapture);
cM.addComponent(mpPlayer);
Command [] cmds = new Command[1];
cmds[0] = new Command("Done") {
public void actionPerformed(ActionEvent evt) {
//do Option1
}
};
Dialog.show(editType, cM, cmds);
When running in the simulator, clicking on the CaptureMedia button, it will present the file chooser interface. But then I am unable to choose any file at all whether audio or video because the choose file button is diabled.
How do I get to test the video capture in the simulator?
I think it's a layout problem, you are adding the MediaPlayer component before the video was created, so it's preferred size is 0.
Try to place the video in the border layout center so it's preferred size is ignored and the player will have enough space to display.
Try this:
final Form hi = new Form("Hi World");
hi.setLayout(new BorderLayout());
final Button bCapture = new Button("Capture Media");
bCapture.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ect) {
try {
final MediaPlayer mpPlayer = new MediaPlayer();
String value = Capture.captureVideo();
System.out.println("Captured Video " + value);
if (value != null) {
System.out.println("Playing Video");
InputStream is = FileSystemStorage.getInstance().openInputStream(value);
String strMime = "video/mp4";
System.out.println("Input Stream" + is.available());
mpPlayer.setName("bla");
mpPlayer.setDataSource(is, strMime, new Runnable() {
public void run() {
System.out.println("reset the clip for playback");
}
});
hi.addComponent(BorderLayout.CENTER, mpPlayer);
hi.revalidate();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
);
hi.addComponent(BorderLayout.NORTH, bCapture);
hi.show();
There is a regression in playing local videos in the Codename One simulator although it should work on the device. The next update of Codename One will fix it but for now you can workaround it by playing from a stream which should work just fine.
Just use the FileSystemStorage class to get an InputStream to the video and invoke the appropriate playback code. Note that this is less efficient than the play via URL API so when the regression is fixed you should probably return to the URL based API.

HTML and webbrowser

I tried to use html page in my code for that i found way from kichensink application, i am using same code and same page.html file applicatin working on simulator but not working on devices. Ondevices i got a blank screen. Below is my code. Please help me on this.
void ShowForm()
{
Form f = new Form("testweb");
Container cnt = new Container(new BorderLayout());
cnt = createDemo();
f.setLayout(new BorderLayout());
f.addComponent(BorderLayout.CENTER, cnt);
f.show();
}
public Container createDemo() {
Container cnt = new Container(new BorderLayout());
final WebBrowser wb = new WebBrowser();
if(wb.getInternal() instanceof BrowserComponent) {
Button btn = new Button("Add");
final TextArea content = new TextArea();
Container north = new Container(new BorderLayout());
north.addComponent(BorderLayout.CENTER, content);
north.addComponent(BorderLayout.EAST, btn);
cnt.addComponent(BorderLayout.NORTH, north);
content.setHint("Add to web document");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
((BrowserComponent)wb.getInternal()).execute("fnc('" + content.getText() + "');");
}
});
((BrowserComponent)wb.getInternal()).setBrowserNavigationCallback(new BrowserNavigationCallback() {
public boolean shouldNavigate(String url) {
if(url.startsWith("http://sayhello")) {
// warning!!! This is not on the EDT and this method MUST return immediately!
Display.getInstance().callSerially(new Runnable() {
public void run() {
((BrowserComponent)wb.getInternal()).execute("fnc('this was written by Java code!');");
}
});
return false;
}
return true;
}
});
}
cnt.addComponent(BorderLayout.CENTER, wb);
wb.setURL("jar:///page.html");
return cnt;
}
Hi,I did few changes setlayout for container and add to another cotainer with scrollable true for container and scrollable false for form but now it's giving me error on devices and error is: "web page not available" page.html not found. Whereas page.html is already placed in src with .res file and application on simulator working fine.
Regards,
Jeny
You can't make a border layout scrollable, including nested scrollables and scrolling native+Codename One widgets in sync is probably not a good idea.
Which device are you having a problem on? There was an issue with browser component on Android for some use cases, its fixed now.

Resources