Using an Android aar library in a Gluon JavaFXPorts project - android

my question is simple enough. I am using Gluon's plugin for Eclipse and developing an application in JavaFX to run on Android. However, I need to use an Android library (.aar format) and after a while of trying, cannot. Does anybody know how I can do this? I have already tried just using the classes.jar inside the .aar, while this has sort of worked, there are a few resources and things I believe the library is missing that is essential to its function. Thank you.
Edit: The library I'm trying to use is CloudRail, the download is here (Direct download)
Currently, using the classes from the extracted classes.jar it is somewhat functional but when the activity from their library is launched (com.cloudrail.si.servicecode.commands.awaitCodeRedirect.AuthenticationActivity) it is displayed however it is blank and there is nothing in it. I am currently under the assumption that this is incorrect and that the missing resources/files are the cause of this.

I've managed to extract the classes.jar from the aar file and add it to a Gluon project as dependency.
Next, I added the activity to the AndroidManifest.xml file, after the main FXActivity:
<activity android:name="com.cloudrail.si.servicecode.commands.awaitCodeRedirect.AuthenticationActivity" />
Then I created a class in the Android package, provided the required credentials to access to Google Drive.
public AndroidTestAar() {
GoogleDrive cs = new GoogleDrive(FXActivity.getInstance(), "****","****");
new Thread() {
#Override
public void run() {
List<CloudMetaData> metas = cs.getChildren("/");
Log.i("info", "Folder has " + metas.size() + " children");
for (CloudMetaData meta : metas) {
Log.i("info", "Child: " + meta.getName());
}
}
}.start();
}
This class is called from the View:
public BasicView(String name) {
...
button.setOnAction(e -> {
try {
Class c = Class.forName("com.testaar.AndroidTestAar");
c.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {}
});
}
I could deploy the apk and run it.
The activity runs outside the JavaFX app, in an Android WebView.
First it asked me to sign in with my user/password, then it asked me about allowing offline access, and finally on the console it successfully listed all my files.

Related

Testing inconvenience: Android Studio JUnit vs Gradle based: testOptions ignored by Android Studio

The following was done with Android Studio 3.4, Android Gradle Plugin 3.3.2 and Gradle 4.10.3.
In the build.gradle file, I have configured some unit test options like this:
android {
testOptions {
unitTests.all {
systemProperty "debug","true"
}
}
}
I do have a test function that tries to read this property:
package com.demo;
public class SysPropTestDemo {
#Test
public static void dumpSysProps() {
System.out.println("sysprop(debug)=" + System.getProperty("debug"));
}
}
When run via command line gradlew test --test com.demo.SysPropTestDemo I will get the property debug set correctly to true. If I run the same test via Android Studio without setting any options, the value shown will be null.
In order to get the same result from Android Studio, I explicitly have to enter some values in the "Run/Debug Configurations" panel, i.e something like -Ddebug=true in the VM options.
Now this is a trivial example, but what I really want to do, is to add some path to the java.library.path property in order to be able to load a JNI library compiled within the project. (I do need to write some tests that make use a modified SQLite lib, so not using JNI is not an option here)
It does work when setting additional options, but I think this is very inconvenient, since I can't enter a variable based value in the configuration options (or at least, I don't know how to). To sum it up: when setting or changing values, I do have to go through a bunch of config screens where I would really prefer to have one place in a config file.
Shouldn't Android Studio somehow make use of the values specified in the build.gradle file? If not, the docs don't make it clear that the testOptions.unitTests.all settings can only be used via gradlew invocation.
Skybow,
I feel you have two questions
1. How to load jni lib for androidTest(not for 'test[non instrumented unit tests])
- copy your jni library in corresponding folder [JNI libraries: [app/src/androidTestFLAVORNAMEDebug/jniLibs]
- load your jni library
static {
try {
System.loadLibrary("xyzjni");
} catch (Exception e) {
Logger.error("Exception on loading the jni library : " + e.getMessage());
}
}
2. How to make android studio use your config variables defined for unitTests.
- It would have great if some text file is there which has all configs.
- Or it is part of build.gradle
- I don't have any detail on this.

Debugging Android in custom libraries

I have just created a react-native library using react-native-create-library and imported it into my master react-native project.
There are some issues I'm having because (honestly) I lack the knowledge.
The problem is that there are no errors (using logcat) and I don't know how I can debug the android part of my imported library.
Example
public class RNZappsCameraModule extends ReactContextBaseJavaModule
implements ActivityEventListener {
#ReactMethod
public void myJavascriptMethod() {
// I want a breakpoint here
// cameraIntent initialization happens here
try
{
currentActivity.startActivityForResult(cameraIntent, requestCode);
}
catch (ActivityNotFoundException e)
{
e.printStackTrace();
}
}
#Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data)
{
// I want a breakpoint here
}
}
The camera intent starts fine, but I believe onActivityResult is never hit.
I know I could log everything and read it, but that won't explain why the result is never returned to my app since there are no errors in the first place.
Google and the official RN documentation are not being my friend at the moment, so please put me on the right track.
Found it.
No rocket science here. I don't know how I managed to do it in the end...
Anyheeew, to give this question a reasonable answer for passers-by...
First off, you need a react-native (master) project in order to actually run your library in a react-native context.
So create it and import your library. The easiest way to do this is by pushing your library into a git repository and adding your library in the package.json of you master project like this:
"react-native-your-package": "git+https://your-git-url-here",
Now install it: npm install react-native-your-package
In order to debug your library:
Open the android project of your react-native project in Android Studio
In menu => view => Tool window, click Build Variants
The new window displays the build types for you project and loaded modules
Click the Build Variant dropdown next to the module you want to debug and select 'debug'
Debug the master Android project
In the projects view, you can expand your module and place breakpoints where ever you like
Click the debug button and fix errors you never head of

Can we use OpenCV in android JUnit test?

I am now writing a test case under "app/src/androidTest", which need to involve OpenCV lib.
I've tried :
1. Import OpenCV 3.2.0 as a module.
2. Import OpenCV lib as suggested , Here is the link.
But anyway the import seems to fail,
```
static {
if (!OpenCVLoader.initDebug()){
Log.w(TAG, "static initializer: Load opencv failed !!!");
} else {
Log.i(TAG, "static initializer: Load opencv succeed .");
}
}
```
Any comment would by helpful.
I had the same problem.
To load OpenCV for android test (on Windows)
Download the OpenCV version for Windows and unzip it.
Copy the following file inside your android project (I putted it inside /app/src/main/jniLibs/win/) :
"yourunzipath" + opencv\build\java\x64\opencv_java331.dll
Then, inside your Android test folder, create the following class :
public class OpenCVTestInitializer {
#Before
public void initOpenCV() {
String projectPath = System.getProperty("user.dir");
String opencvpath = projectPath + "/app/src/main/jniLibs/win/";
System.load(opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll");
}
}
To finish, each test class you want to use with OpenCV must extend the previous class.

Error google-play-services_lib\AndroidManifest.xml not found or not a file with Robolectric 2 and Google Play Services (maps V2)

I have an Android application with Google Maps V2 configured with maven in Eclipse. So I have a "mavenised" Google Play Services lib in the worspace, and the app pom has two maven dependencies to google-play-services jar and apklib.
I implemented a dummy test which only checks if a map fragment is not null:
#RunWith(RobolectricTestRunner.class)
public class MapsTest {
private GoogleMap map;
private ElementMapActivity activity;
#Before
public void setUp() throws Exception {
activity = new ElementMapActivity();
activity.onCreate(null);
}
#Test
public void mapExists() {
// Try to obtain the map from the SupportMapFragment.
map = ((SupportMapFragment) activity.getSupportFragmentManager()
.findFragmentById(R.id.elementMap)).getMap();
Assert.assertNotNull(map);
}
}
Note: a similar code is used in the real application activity to show the map, and it runs OK.
I don't implement any custom testrunners.
I run the test with maven: mvn test.
With Robolectric 1.2 the test builds and executes, but the assertNotNull fails, as the map instance is null. The fragment is not correctly recovered.
With Robolectric 2.1.1 the test builds but fails to execute. I get an exception for each test in the project (not only for the one that tests the maps):
WARNING: no system properties value for ro.build.date.utc
java.lang.RuntimeException: .\..\google-play-services_lib\AndroidManifest.xml not found or not a file; it should point to your project's AndroidManifest.xml
at org.robolectric.AndroidManifest.validate(AndroidManifest.java:108)
at org.robolectric.AndroidManifest.getResourcePath(AndroidManifest.java:274)
at org.robolectric.AndroidManifest.getIncludedResourcePaths(AndroidManifest.java:280)
at org.robolectric.AndroidManifest.getIncludedResourcePaths(AndroidManifest.java:282)
at org.robolectric.RobolectricTestRunner.createAppResourceLoader(RobolectricTestRunner.java:576)
at org.robolectric.RobolectricTestRunner.getAppResourceLoader(RobolectricTestRunner.java:568)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:89)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:387)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:227)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:120)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:103)
at org.apache.maven.surefire.Surefire.run(Surefire.java:169)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
It seems that Robolectric tries to use the google-play-services library manifest instead of the main application manifest, which is in the default location: the app root folder. The library manifest is in it's own root folder as well.
Am I missing some configuration for the tests? Should I use a custom testrunner? Or is it that Google Maps V2 are not supported with Robolectric 2?
Edit: I can do without the maps tests. The problem is that with Robolectric 2 all the other tests get this error too, just by having the google-play-library dependency, so I can not use Robolectric 2 by now. I would like to know if this is a known bug in order to decide to go back to Robolectric 1 or not. I checked Robolectric bug reports and didn't find anything about this.
I have recently encountered the same problem with ActionBarSherlock when running my Robolectric tests under my Maven build plan.
The problem was not evident when I was completing builds on a Windows machine and only became apparent after I switched my laptop for a OSX power device.
I found that the problem was that the library name "google-play-services_lib" doesn't (exactly) match that of the folder name in the directory structure. In my case, my Eclipse project was called "ActionBarSherlock-4.3.1" whereas the folder itself was called "actionbarsherlock" under the file system.
I recommend that you synchronise the two names (Eclipse project and file system) and re-run your tests. Hope that helps.
Testing Android Apps, with Robolectric 2.1.1, that use google-play-services_lib (Google Maps) produces AndroidManifest.xml not found RuntimeException.
The short answer is here in bold. The long answer is below it.
Look in your project for a file named project.properties
Create a new file called test-project.properties
Override any or all of the android.library.reference.$
For example in my project.properties it had this library reference:
**android.library.reference.1=../../../ADK/adt-bundle-windows-x86_64-20130522/sdk/extras/google/google_play_services/libproject/google-play-services_lib**
I overrode it in the test-project.properties file
android.library.reference.1=res
Put the AndroidManifest.xml from the google-play-services_lib into the res(or any folder in the project) folder of the project you are testing
The long answer:
I was having the same issue and was thinking the problem was the same as described above "google-play-services library manifest instead of the main application manifest" So I removed all my references to the google-place-services_lib and still received the error. I downloaded the 2.1.1 Robolectric code from github and started debugging through it. I found that org.robolectric.AndroidManifest class has a method called getLibraryManifests which calls createLibraryManifests and that calls findLibraries. One of the things it does is loads the project.properties file in your project. In my case my project.properties file at this content:
android.library.reference.1=../../../ADK/adt-bundle-windows-x86_64-20130522/sdk/extras/google/google_play_services/libproject/google-play-services_lib
This was created when I used the Android Tools for the google play services install per Google's documentation. If you comment out that line from project.properties file then the error goes away. A better solution is to leave it and then create your own file called test-project.properties and put in the correct directory for android.library.reference.1 and the AndroidManifest will override the original value.
Here is the relevant code from AndroidManifest.java
protected List<FsFile> findLibraries() {
FsFile baseDir = getBaseDir();
List<FsFile> libraryBaseDirs = new ArrayList<FsFile>();
Properties properties = getProperties(baseDir.join("project.properties"));
// get the project.properties overrides and apply them (if any)
Properties overrideProperties = getProperties(baseDir.join("test-project.properties"));
if (overrideProperties!=null) properties.putAll(overrideProperties);
if (properties != null) {
int libRef = 1;
String lib;
while ((lib = properties.getProperty("android.library.reference." + libRef)) != null) {
FsFile libraryBaseDir = baseDir.join(lib);
libraryBaseDirs.add(libraryBaseDir);
libRef++;
}
}
return libraryBaseDirs;
}

SAXNotRecognizedException while using gdata api's for youtube integrating in android?

I am integrating youtube in my android app. I am using gdata youtube library for the same.
`
YouTubeManager ym = new YouTubeManager(clientID);
List<YoutubeVideo> videos;
try {
videos = ym.retrieveVideos(textQuery, maxResults, filter, timeout);
for (YoutubeVideo youtubeVideo : videos) {
System.out.println(youtubeVideo.getWebPlayerUrl());
System.out.println("Thumbnails");
for (String thumbnail : youtubeVideo.getThumbnails()) {
System.out.println("\t" + thumbnail);
}
System.out.println(youtubeVideo.getEmbeddedWebPlayerUrl());
System.out.println("************************************");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} `
I have imported jar's as under,
activation.jar
apache-mime4j-0.6.jar
gdata-core-1.0.jar
gdata-media-1.0.jar
gdata-youtube-2.0.jar
google-collect-1.0-rc2.jar
httpmime-4.0.3.jar
mail.jar
servlet.jar
Now I am getting an exception SAXNotRecognizedException at
videos = ym.retrieveVideos(textQuery, maxResults, filter, timeout);
plz can any one tell me what is happening wrong over here. How to fix this error? Or any other way to integrate youtube in android app.
The root cause is reported as Issue 9493.
http://code.google.com/p/android/issues/detail?id=9493
And a workaround for it can be found here:
http://darutk-oboegaki.blogspot.com/2011/11/solution-for-gdata-java-clients.html
SecureGenericXMLFactory in gdata-core intentionally disables some features, but some of them are needed to retrieve data from YouTube. The basic idea of the work around is as follows.
(1) Remove the original SecureGenericXMLFactory from gdata-core-1.0.jar
cd gdata-src.java-1.46.0/gdata/java/lib
mkdir gdata-core-1.0-no-SecureGenericXMLFactory
cd gdata-core-1.0-no-SecureGenericXMLFactory
jar xf ../gdata-core-1.0.jar
rm -rf com/google/gdata/util/common/xml/parsing
jar cfm ../gdata-core-1.0-no-SecureGenericXMLFactory.jar META-INF/MANIFEST.MF com
(2) Replace the original gdata-core-1.0.jar with the new one created by the step (1). (in Eclipse)
(3) Copy the original source code of SecureGenericXMLFactory to your Android project.
(4) Add an unconditional 'return' in the constructor of SecureSAXParserFactory before the code lines that disable the necessary features.
// "if (true)" was added to avoid a compilation error in Eclipse.
if (true)
{
return;
}

Categories

Resources