I'm working on a PhoneGap/Cordova plugin that's supposed to provide a socket for sending and receiving OSC messages (Open Sound Control). For that purpose I'd like to use JavaOSC but I'm uncertain about how to include the library into my project.
I'm using Android Studio and I've basically followed this tutorial to set up my project. First I placed the raw JavaOSC class-files in the same directory as my OSCPlugin.class and placed the import declarations at the to of my OSCPlugin.class:
import com.illposed.osc;
That didn't work.
As a next step I tried to add the library from maven within the project's module settings. I was able to download the jar files from maven and install put them into /platforms/android/libs. Within the settings for the module 'android' I can see that 'Android API 17' is supposed to be used as SDK, including cordova-3.1.0 and com.illposed.osc:javaosc-core:0.2 - both activated. I can see the cordova-3.1.0.jar as well as javaosc-core-0.2.jar, containing com.illposed.osc in the navigator within Android Studio.
However, when trying to compile my project I get:
Gradle: cannot find symbol class osc
triggered from within OSCPlugin.class that contains the above mentioned import declaration
I have very little experience with Java and even less with Android development. But I'd be interested in solving this riddle and get started. I have searched the Java docs but the problem doesn't merely lie within Java but rather within the structure of the Android project.
I'd be thankful if someone could shed some light on this issue. Any hint's highly appreciated!
For one of my Phonegap projects I needed the Apache Commons Net, trying to follow these steps:
...
<source-file src="src/android/xxx.jar" target-dir="libs" framework="true" />
<source-file src="src/android/MyPlugin.java" target-dir="src/com/mypackage" />
...
unfortunately, without success. The trick was to embed the third-party library in another plugin (following the very plugin structure). Having the org.apache.commons.net as a top level directory:
org.apache.commons.net
+src
+android(this is where the .jar is located)
+www (empty, not referencing any .js)
+plugin.xml
For brevity, plugin.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
id="org.apache.commons.net"
version="0.1.0">
<name>org.apache.commons.net</name>
<description>org.apache.commons.net</description>
<license>Apache License, Version 2.0</license>
<keywords>org.apache.commons.net</keywords>
<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="org.apache.commons.net">
<param name="android-package" value="org.apache.commons.net"/>
</feature>
</config-file>
<source-file src="src/android/commons-net-2.2.jar" target-dir="libs" framework="true" />
</platform>
</plugin>
Assuming the org.apache.commons.net directory is located in your local git repo, adding it to your project is as trivial as:
phonegap local plugin add /path/to/your/org.apache.commons.net
To add external library, basically all you have to do is copy the jar to the /libs folder.
Here you have a bad import in your source.
import is used to import a class by specifying the package name followed by the class name and here you only specify the class name, so the error "cannot find symbol class osc" you are having is because there is no class osc.
You should use either
import com.illposed.osc.*; if you want to import all classes from the package
or add an import for each class from the package that you are going to use.
And if you want make the plugin installable using the CLI or phonegap build, you also have to update plugin.xml to add the copy of the jar file.
ps in case you don't know, you won't be able to use classes from com.illposed.osc.ui as they are using swing and designed for the jvm and not android.
Related
I’m writing a Java-programm for school that also uses Thrift.
The problem is not so much the general programm/programm-logic itself, but just importing Thrift (to use it in a specific part).
My basic -possibly wrong- understanding is that you write the programm-code (here empfaenger.java), then you import Thrift into this file by adding the needed import-statements, e.g.:
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket ;
import org.apache.thrift.transport.TTransport;
and adding a file in the same directory from which they can actually can be imported, in this case libthrift-0.13.0.jar.(1) Then you later also import a compiled .thrift-file with the language-specific realization oft he IDL-code, that iself again imports some Thrift-classes. This file is here named syncautohersteller.
EDIT: The approach with the .jar-file was recommended by the prof.
Current project-structure (as seen in InteliJ):
The problem is now just that all the Thrift import-statements all throw errors, e.g.
empfaenger.java
java: package org.apache.thrift does not exist
syncautohersteller
package javax.annotation does not exist
so clearly i’m doing something wrong.
Does anybody know how to fix this?
(1) I got the file from the Thrift folder (Home/Downloads/thrift-0.13.0/lib/java/build/libs and then the first of the three .jar-files in the folder) after installing Thrift using ./configure, sudo make and sudo make install and trying to verify by running “~/Downloads/thrift-0.13.0$ thrift –version” with result
Thrift version 0.13.0
In IntellJ Idea to add external Jars you can find some useful information in this question: Correct way to add external jars (lib/*.jar) to an IntelliJ IDEA project.
I suggest you to manage the project's dependencies through Maven, which help you to add JAR dependencies to the classpath in a simpler way.
First, you have to convert your project into a Maven project as explained in IntelliJ Idea documentation.
Then you can follow these steps:
Go to Maven repository website
Search for Thrift
Select first result
Select the version you need
Copy the maven dependency
org.apache.thrift
libthrift
0.13.0
Add maven dependency to your pom.xml file
Execute a mvn clean install, after clicking the following button in IntelliJ
This process will help you and people which work with you to manage in a simpler way the dependencies of the project.
You can do it the simplest way with the Gradle, something like this:
build.gradle.kts:
repositories {
mavenCentral()
}
dependencies {
implementation("org.apache.thrift:libthrift:0.13.0")
}
When trying to write a class that extends I get the error message:
The hierarchy of the type 'MYEditor' is inconsistent.
import org.eclipse.cdt.internal.ui.editor.CEditor;
public class MYEditor extends CEditor {
}
This answer says:
These errors happened because some interface/class in the hierarchy
cannot be resolved.
This indicates that eclipse cannot find a class in the hierarchy. But when I use the class in my plugin.xml, it works. I am using it like this:
<editor
class="org.eclipse.cdt.internal.ui.editor.CEditor"
contributorClass="org.eclipse.cdt.internal.ui.editor.CEditorActionContributor"
default="true"
filenames="*.grasp, *.c"
icon="icons/small.png"
id="de.blub.ide.myeditor"
name="My Editor">
</editor>
This works, but lacks a few features that I need for my plugin. That's why I want to use a class that inherits from CEditor.
This answer didn't work, to (remove and add JRE System Library).
I've also read that the jar file needs to be put in the Classpath section of the plugin.xml. But the "Add" and "New" Buttons don't provide a way to chose an external jar file. I can manually copy that jar file from "~/.p2/pool/plugins" into my projects lib folder, but that didn't help.
Plug-ins reference code in other plug-ins by including the other plug-in in their dependencies list. This is the Require-Bundle entry in the plug-in's MANIFEST.MF.
In the MANIFEST.MF/plugin.xml/build.properties editor you can set the dependencies in the 'Required Plug-ins' section on the 'Dependencies' page.
Do not copy plugin jars, do not put plugin jars in the Java Build Path.
But note that extending internal classes is against the Eclipse API Rules of Engagement. Internal classes may change without warning and may be different in older releases.
The CDT Plug-in Programmer's Guide covers the official APIs for Eclipse CDT.
I have a Cordova project created using Visual Studio 2015's Tools for Apache Cordova. We're trying to create a plugin that uses an external library, and that library depends on various things such as Google's location services. I've found that they go in a .gradle file, but have no idea how to get them in that file using TACO. I can do it manually, but VS regenerates the .gradle file every time the project's built.
I'm new to TACO, so it may be I'm missing something.
Very common problem when starting out with Cordova Plugins. I've struggled with this in the past. Start by reading this. You need to add some entries to your plugin.xml file. In that file you should have a section for each platform you support. You should also not be modifying the platform/android/build.gradle file directly. Make a separate one which will eventually get it's contents appended to your platform/android/build.gradle using <framework>.
<platform name="android">
</platform>
In platforms add something similar to match your features:
Permissions docs
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
....
</config-file>
External Libs docs
<framework src="src/android/build.gradle" custom="true" type="gradleReference" />
<source-file src="lib/android/sample-android-sdk/sample.jar" custom="true" target-dir="lib" />
As i wanted to develop an App with Estimote Beacons i searched for it and found the Xamarin Component Estimote SDK for Android. However, the Version is outdated so i began to try including the estimote sdk for android on myself. With .aar/.jar Binding.
I saw three Options:
fully compile the library and be able to use it as C# Classes
write a wrapper and only let the wrapper interpret and use those classes.
natively call functions from the Library with JNI
Compiling the whole library did not work due to about 102 Errors while building. Working with metadata.xml did not work although i was able to reduce the amount of Errors to 45.
Natively calling functions with JNI is a pain and no option because the Library is too big.
Writing a wrapper nearly worked
I stripped the classes from the estimotesdk.aar so i have only the classes.jar from the inside.
Wrote a Library as wrapper and put that in another jar:
EstimoteSDK.jar --> ReferenceJar
EstimoteWrapper --> EmbeddedJar
I can build the ClassLibrary Project in Visual Studio without Problems. I can even use the classes from the Wrapper in C#.
But now my Problem is:
MissingMethodException and NoClassDefFoundError during Runtime
I found out the following:
The EstimoteSDK.jar and its Class-Files change after building .
For some reason, the EstimoteSDK.jar is not only copied but also modified and loses some functions and even classes.
Proof (used dex2jar tool to get the jar out of the .dex in the builded apk):
The right class File contains less functions than the right
Now my Question:
how can i prevent Xamarin or any other Component from touching the EstimoteSDK.jar and stripping functions and classes from it ?
Setup:
Visual Studio 2015 Professional
Xamarin.Forms 2.0
Windows 7
Android and iOS-App
So, after posting my question to xamarin forums where someone provided a updated version of estimotesdk ( i did not try that so far) and trying out everything i could imagine i found a solution for me:
I have two Jars (EstimoteSDK and my own written Wrapper). Including them with the correct Build Action did it for me:
EstimoteSDK.jar --> EmbeddedReferenceJar
List item --> EmbeddedJar
So this is the correct way to include a native library which is accessed by a wrapper class.
The magic word could be LinkerPleaseInclude.cs. Add a class that references the class / calls the function. But I don't know if your wrapper is in the way, because you aren't binding the estimote lib in the usual way.
public class LinkerPleaseInclude
{
public void Include(Beaconmanager manager)
{
manager.RegionExitExpiration = 0L;
}
}
btw: there is a crossplatform abstraction for estimote: https://www.nuget.org/packages/Estimotes.Xplat/. But it might use the outdated version you mentioned.
Edit:
metadata.xml for Estimote
<metadata>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.okhttp_v2_2_0.com.squareup.okhttp.internal.http']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.gson_v2_3_1.com.google.gson.internal.bind']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.gson_v2_3_1.com.google.gson.internal']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.gson_v2_3_1.com.google.gson']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.okio_v1_3_0.okio']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.maven_v3_3_3']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.connection.internal.protocols']"></remove-node>
<attr path="/api/package[#name='com.estimote.sdk.connection.settings']/class[#name='Version']/method[#name='compareTo' and count(parameter)=1 and parameter[1][#type='com.estimote.sdk.connection.settings.Version']]/parameter[1]"
name="type">Java.Lang.Object</attr>
<attr path="/api/package[#name='com.estimote.sdk.cloud.internal']/class[#name='ChallengeResponse']/field[#name='challengeResponse']" name="name">ChallangeResponseString</attr>
<attr path="/api/package[#name='com.estimote.sdk.cloud.model.google']/class[#name='Beacons']/field[#name='beacons']" name="name">BeaconList</attr>
<attr path="/api/package[#name='com.estimote.sdk.cloud.model.google']/class[#name='Observations']/field[#name='observations']" name="name">ObservationList</attr>
</metadata>
I am currently developing an Android app using cordova 2.0. Obviously the plugins.xml has been depreciated and everything is now housed in config.xml. I was just wondering if anyone has managed to get the Phonegap Screenshot plugin working in Eclipse and Cordova 2.0 working on android.
Plugin can be found:
https://github.com/josemando/phonegap-plugins/tree/master/Android/Screenshot
I have added:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
to my Android manifest xml. And made sure that:
<plugin name="Screenshot" value="org.apache.cordova.Screenshot"/>
is added to my config.xml (that now contains all plugin information from plugin.xml)
Screenshot.js is added to the directory:
assets/www/js/
However I am unsure where exactly to place the Screenshot.java file. The example has it in:
src / org / apache / cordova /
However as I did not have this directory I simply placed it in:
src/uk.co..appname1.appname2/
When I did this however it produced errors, the first one being:
The declared package "org.apache.cordova" does not match the expected package "uk.co.mysitename.appname1.appname2" Screenshot.java /Project Name/src/uk/co/mysitename/appname1/appname2line 8 Java Problem
This refers to this line in the Screenshot.js:
package org.apache.cordova;
The two suggested actions to fix this are to:
Move 'Screenshot.java' to package 'org.apache.cordova' (this directory doesn't exsist atm)
Or change package directory to 'uk.co.mysitename.appname1.appname2'
The second error says:
The method run() of type new Runnable(){} must override a superclass method
The suggested action for this being to "remove '#override' annotation"
I have tried to do every possible combination of these however I cannot seem to make progress and get it all to link up. Usually because it thinks that CordovaRef isn't referenced. I am unsure if the plugin even works on Cordova 2.0.0. I have some experience with Phonegap/Cordova but only in ios with Xcode and Objective C plugins. I am new to Java, Eclipse and Android. Any help or clarification on any of these matters would be greatly appreciated.
Answer resolved by:
Phonegap Screenshot plugin in Cordova 2.0.0
Answer/solution provided by Simon MacDonald