I have created a simple sample Application with CodeNameOne without any changes.
Certificate and Provisioning file is available and configured as project properties.
IDE: Eclipse
Desktop OS: Windows
Executing 'Send IOS Debug Build' starts the server build and shows the
following error:
/var/folders/p7/d3z112yd0156kxkm2p21p8ym0000gn/T/build5327647990993852705xxx/stub/TestBuildDeployStub.java
/var/folders/p7/d3z112yd0156kxkm2p21p8ym0000gn/T/build5327647990993852705xxx/stub/TestBuildDeployStub.java:14:
error: cannot find symbol private TestBuildDeploy i;
^ symbol: class TestBuildDeploy location: class TestBuildDeployStub
/var/folders/p7/d3z112yd0156kxkm2p21p8ym0000gn/T/build5327647990993852705xxx/stub/TestBuildDeployStub.java:23:
error: cannot find symbol i = new TestBuildDeploy();
^ symbol: class TestBuildDeploy location: class TestBuildDeployStub Note:
/var/folders/p7/d3z112yd0156kxkm2p21p8ym0000gn/T/build5327647990993852705xxx/stub/TestBuildDeployStub.java
uses or overrides a deprecated API. Note: Recompile with
-Xlint:deprecation for details. 2 errors
This is the java class:
package com.canda.mario.myapp;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import com.codename1.ui.Toolbar;
import java.io.IOException;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class TestBuildDeploy {
private Form current;
private Resources theme;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature, uncomment if you have a pro subscription
// Log.bindCrashProtection(true);
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Hi World");
hi.addComponent(new Label("Hi World"));
hi.show();
}
public void stop() {
current = Display.getInstance().getCurrent();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = Display.getInstance().getCurrent();
}
}
public void destroy() {
}
}
If you change the package/class of a Codename One application after it's created you need to change it everywhere both in the project and in the codenameone_settings.properties that is why we recommend never changing it.
We don't make this process easy since you are married to life when creating a package name. This is used to uniquely identify you in the stores and can't be changed ever once an app is submitted so you need to understand that this isn't something you should do... Give package name deep consideration before creating the app!
Related
Since I'm implementing a custom gallery for Android and iOS, I have to access directly to the gallery files stored in the FileSystemStorage through native interfaces.
The basic idea is to retrieve the file list through a native interface, and then make a cross-platform GUI in Codename One. This works on Android, I had to make the thumbs generation (in the Codename One side, not in the native interface side) as fast as possible and the overall result is quite acceptable.
On iOS, I have an additional issue, that is the HEIC image file format, that needs to be converted in JPEG to become usable in Codename One. Basically, I get the file list through the code in this question (I'm waiting for an answer...), then I have to convert each HEIC file to a temporary JPEG file, but my HEICtoJPEG native interface makes the app crashing after few images with an "out of memory" Xcode message...
I suspect that the problematic code is the following, maybe the UIImage* image and/or the NSData* mediaData are never released:
#import "myapp_utilities_HEICtoJPEGNativeImpl.h"
#implementation myapp_utilities_HEICtoJPEGNativeImpl
-(NSData*)heicToJpeg:(NSData*)param{
UIImage* image = [UIImage imageWithData:param];
NSData* mediaData = UIImageJPEGRepresentation(image, 0.9);
return mediaData;
}
-(BOOL)isSupported{
return YES;
}
#end
This is the Java native interface:
import com.codename1.system.NativeInterface;
/**
* #deprecated
*/
public interface HEICtoJPEGNative extends NativeInterface {
public byte[] heicToJpeg(byte[] heicInput);
}
and this the Java public API:
import com.codename1.io.FileSystemStorage;
import com.codename1.io.Util;
import com.codename1.system.NativeLookup;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class HEICtoJPEG {
private static HEICtoJPEGNative nativeInterface = NativeLookup.create(HEICtoJPEGNative.class);
/**
* Public API to convert an HEIC file to a new JPEG file (placed in /heic)
* #param heicFile in the FileSystemStorage
* #return a new file (with unique name)
*/
public static String convertToJPEG(String heicFile) throws IOException {
if (nativeInterface != null && nativeInterface.isSupported()) {
// It ensures that the directory exists.
FileSystemStorage fss = FileSystemStorage.getInstance();
String heicDir = fss.getAppHomePath() + "/heic";
if (!fss.isDirectory(heicDir)) {
fss.mkdir(heicDir);
}
ByteArrayOutputStream outHeic = new ByteArrayOutputStream();
InputStream inHeic = fss.openInputStream(heicFile);
Util.copy(inHeic, outHeic);
byte[] heicData = outHeic.toByteArray();
byte[] jpegData = nativeInterface.heicToJpeg(heicData);
String jpegFile = heicDir + "/" + DeviceUtilities.getUniqueId() + ".jpg";
OutputStream outJpeg = fss.openOutputStream(jpegFile);
ByteArrayInputStream inJpeg = new ByteArrayInputStream(jpegData);
Util.copy(inJpeg, outJpeg);
return jpegFile;
} else {
return null;
}
}
}
Since the Android counterpart works, I hope that the rest of my custom gallery code is fine and that this out-of-memory issue is inside code I posted here.
I hope you can indicate me a working solution. Thank you
There was a memory leak in the way that the iOS port invoked native interface methods which received or returned primitive arrays (byte[], int[], etc..).
I have just committed a fix for this (native interface invocations are now wrapped in an autorelease pool) which will be available on the build server next Friday (October 9, 2020).
EDIT: (Friday October 2, 2020)
This fix has been deployed to the build server already so it you should be able to build it again immediately and see if it fixes your issue.
I am getting some sort of compilation error it seems.
I have ‘Common.java’ class inside ‘base’ package. It's a program for starting firefox driver. That, I have kept it in the separate package to make it a one time effort and modularity purpose.
I am calling this class file inside the child class ‘tc_01.java’. This TC_01.jave program is in another package ‘testing’. This TC_01.java file is actually accessing driver from Common.java and start the browser and try some login and logout actions.
My child class TC_01.java is showing me compilation error and Error Message on Mouse Hover is – > “field Common.driver is not visible”.
And, at Console : "java.lang.Error: Unresolved compilation problems:
The field Common.driver is not visible"
My Analysis: It seems TC_01.java file is not able to access the 'driver' from 'Common.java'.
But, I have already written 'extends' keyword for it to inherit the properties.
Please guide me. Thanks
Here is my code:->
package base;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
public class Common {
public FirefoxDriver driver;
#BeforeMethod
public void BM(){
System.setProperty(“webdriver.gecko.driver”,”D://Rajiv//Selenium//geckodriver.exe”);
driver = new FirefoxDriver();
driver.get(“http://automationpractice.com/index.php”);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#AfterMethod
public void CM(){
driver.close();
}
}
# Pakage – testing; Class – Tc_01.java
package testing;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import base.Common;
public class TC_01 extends Common{
public FirefoxDriver driver;`
#Test
public void TM(){
System.out.println(“Selenium Webdriver Script in Firefox browser using Gecko` `Driver | AutomationPractice.com PAGE LAUNCHED”);
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(“search_query_top”)));
try{
String expectedTitle = “My Store”;
System.out.println(“ExpectedTile = “+expectedTitle );
String actualTitle = driver.getTitle();
System.out.println(“The actual Title of the Page is = “+actualTitle);
Assert.assertEquals(actualTitle, expectedTitle);*/
System.out.println(“Control has reached here”);
driver.findElementByClassName(“login”).click(); // field common.driver is not visible
driver.findElementById(“email”).sendKeys(“*****#yahoo.com”);
driver.findElementById(“passwd”).sendKeys(“*****”);
driver.findElementById(“SubmitLogin”).click();
driver.findElementByClassName(“logout”).click();
System.out.println(“Sucessfully Logout from the Application”);
}catch (Exception e){
e.printStackTrace();
}
}
}
I was able to find the root cause for this issue.
It wasted my 3 days before i asked for help here in this forum.
As i had analysed initially, i had mentioned my driver properties in parent class and was accessing it in Child Class. There was some name mismatch. When it was trying to inherit the properties from parent, it was not accessible and giving me compilation error. I renamed the parent class name to the same name that i was giving while extending in Child Class. And, it worked.
Thanks again to all of you. It is such a wonderful forum to discuss your issue between each other and getting its resolution.
Found the answer to my question: For those having the same problem.
ANSWER: When working with HTTP servlets i needed to have the jars within the WEB-INF/lib directory. Else i could just keep them under the java build path (libraries). Thus in eclispe, right click on lib, then Add Google API's and the select BigQuery.
I am testing out google app engine with big query.
I am able to run big query fine in eclipse when I run it as an app, however when i run it as an HttpServlet i keep getting the following error!
java.lang.NoClassDefFoundError: com/google/api/client/json/JsonFactory
Below is the exact code I am using.
package com.hw3.test;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.bigquery.Bigquery;
import com.google.api.services.bigquery.BigqueryScopes;
import com.google.api.services.bigquery.model.GetQueryResultsResponse;
import com.google.api.services.bigquery.model.QueryRequest;
import com.google.api.services.bigquery.model.QueryResponse;
import com.google.api.services.bigquery.model.TableCell;
import com.google.api.services.bigquery.model.TableRow;
import java.io.IOException;
import javax.servlet.http.*;
import java.util.List;
import java.util.Scanner;
#SuppressWarnings("serial")
public class HelloWord3Servlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Bigquery bigquery = createAuthorizedClient(); //If i comment this out i will get the text below, else i get the error from the title.
resp.setContentType("text/plain");
resp.getWriter().println("\nQuery Results:\n------------\n");
}
private static List<TableRow> executeQuery(String querySql, Bigquery bigquery, String projectId)
throws IOException {
QueryResponse query = bigquery.jobs().query(projectId, new QueryRequest().setQuery(querySql)).execute();
// Execute it
GetQueryResultsResponse queryResult = bigquery.jobs()
.getQueryResults(query.getJobReference().getProjectId(), query.getJobReference().getJobId()).execute();
return queryResult.getRows();
}
public static Bigquery createAuthorizedClient() throws IOException {
// Create the credential
HttpTransport transport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = GoogleCredential.getApplicationDefault(transport, jsonFactory);
// Depending on the environment that provides the default credentials
// (e.g. Compute Engine, App
// Engine), the credentials may require us to specify the scopes we need
// explicitly.
// Check for this case, and inject the Bigquery scope if required.
if (credential.createScopedRequired()) {
credential = credential.createScoped(BigqueryScopes.all());
}
return new Bigquery.Builder(transport, jsonFactory, credential).setApplicationName("Bigquery Samples").build();
}
public static void main(String[] args) throws IOException {
Scanner sc;
if (args.length == 0) {
// Prompt the user to enter the id of the project to run the queries
// under
System.out.print("Enter the project ID: ");
sc = new Scanner(System.in);
} else {
sc = new Scanner(args[0]);
}
String projectId = sc.nextLine();
// Create a new Bigquery client authorized via Application Default
// Credentials.
Bigquery bigquery = createAuthorizedClient();
List<TableRow> rows = executeQuery(
"SELECT TOP(corpus, 10) as title, COUNT(*) as unique_words " + "FROM [publicdata:samples.shakespeare]",
bigquery, projectId);
printResults(rows);
}
private static void printResults(List<TableRow> rows) {
System.out.print("\nQuery Results:\n------------\n");
for (TableRow row : rows) {
for (TableCell field : row.getF()) {
System.out.printf("%-50s", field.getV());
}
System.out.println();
}
}
}
I got this code directly from the google website although i did modify it slightly so that i can test out app engine. However it will not work when using app engine.
Any help is greatly appreciated!
It sounds like dependencies aren't configured correctly when you are running as an HttpServlet. How do you tell your app which dependencies to use? What version are you trying to load? Is that version available in Google App Engine?
Note that the specific version of the jackson libraries you require change depending on what environment you are running in. See https://developers.google.com/api-client-library/java/google-http-java-client/setup for a list of dependencies you need in various environments.
ANSWER: When working with HTTP servlets i needed to have the jars within the WEB-INF/lib directory. Else i could just keep them under the java build path (libraries). Thus in eclispe, right click on lib, then Add Google API's and the select BigQuery.
I'm building an app that should periodically capture the user's location (I'm looking for every 60 minutes), tracking the cities they've visited.
I first started off using the foreground location listener and it was perfect, it seems to fire every few minutes but I've put checks in place so that it only actually tracks a location if enough time has passed. When I switch to other apps it looks like the foreground listener will continue to fire for a period of time, and then just stop firing, which to me makes sense since I'm thinking the OS is backgrounding the app. At which point, I would expect the background listener to have been registered and wake the app when that listener is fired.
On to my question... I'm having trouble with the background location listener. I understand that it won't fire on simulator, but it's also not firing when I build debug (using built-in certificate) to my device. For the sake of this question I've distilled what my app is doing down to barebones, based off the example listed here: https://gist.github.com/shannah/86c739edac34216d3c4d
Just to be sure I tried switching the background listener to the standard foreground one (.setLocationListener(new BackgroundListener())), and running on the simulator, I can verify that my label gets updated with appropriate data.
I also had done some testing on my actual app where I would pop a dialog in the no-arg constructor to say the listener was initialized, and another dialog when locationUpdated was called. I was able to see the popup on init, but there was no dialog on locationUpdated, which led me to believe my device was never firing it.
The device I'm testing on is a Samsung S4 with Android 5.0.1 (Lollipop).
Here is the test application I wrote which closely mimics what my actual application is doing.
bglocation.java
package com.bglocation;
import java.util.List;
import com.codename1.io.Storage;
import com.codename1.location.LocationManager;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class bglocation {
private Form current;
private Resources theme;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Hi World");
LocationManager.getLocationManager().setBackgroundLocationListener(BackgroundLocationListener.class);
String lastCheckin = (String)Storage.getInstance().readObject("LOCATION");
String label = "No checkins.";
if (lastCheckin != null) {
label = lastCheckin;
}
Label hiLabel = new Label("Last checkin: " + label);
hi.addComponent(hiLabel);
hi.show();
}
public void stop() {
current = Display.getInstance().getCurrent();
}
public void destroy() {
}
}
BackgroundLocationListener.java
package com.bglocation;
import java.util.Date;
import com.codename1.io.Storage;
import com.codename1.location.Location;
import com.codename1.location.LocationListener;
public class BackgroundLocationListener implements LocationListener {
#Override
public void locationUpdated(Location location) {
Storage.getInstance().writeObject("LOCATION", new Date().toString());
}
#Override
public void providerStateChanged(int newState) { }
}
The background listener is invoked once there is a significant location change, it is also running on a completely different process so you don't really have a UI or access to your application instance.
What you need to do to communicate with your app is firing a local notification or launching an intent or storing the location into a file or a database and once your app is launched get the data from there.
How should I loop a video in JavaFX?
I'm trying to just play a video one time after another, so I was looking for some sample code in many places and I could'nt make it work!
This is what doesn't work for me:
public MyMediaPlayer (){
media = new Media(getVideo());
mediaPlayer = new MediaPlayer(media);
mediaView = new MediaView(mediaPlayer);
startMediaPlayer();
}
private String getVideo() {
return getClass().getResource("videos/limbo.mp4").toString();
}
public final void startMediaPlayer() {
mediaPlayer.setMute(true);
mediaPlayer.setCycleCount(javafx.scene.media.MediaPlayer.INDEFINITE); //this is the line that should do the magic, but it doesn't...
mediaPlayer.play();
}
The following works for me (video loops forever). I can't replicate your issue.
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.media.*;
import javafx.stage.Stage;
public class VideoPlayerExample extends Application {
public static void main(String[] args) throws Exception { launch(args); }
#Override public void start(final Stage stage) throws Exception {
final MediaPlayer oracleVid = new MediaPlayer(
new Media("http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv")
);
stage.setScene(new Scene(new Group(new MediaView(oracleVid)), 540, 208));
stage.show();
oracleVid.setMute(true);
oracleVid.setRate(20);
oracleVid.setCycleCount(MediaPlayer.INDEFINITE);
oracleVid.play();
}
}
I'm under Java 7, doesn't work there . . . the problem seems to be MP4 format.
If you can't play MP4 files, either:
The MP4 is not encoded in a format JavaFX understands (the JavaFX 2.2 Media javadoc details the allowed formats).
OR
You don't have appropriate codecs installed on your machine to allow the MP4 file to be decoded. See the JavaFX 2.2 Media system requirements for information on what you need to install on your machine to allow MP4 files to be displayed.