Calling static jar function from Unity3D - android

I made and compiled a Android Library, containing a simple class and a simple static function:
package moo;
public class MyTestClass {
public static String Foo(){
return "Foo from Moo";
}
}
I placed the .jar in my Assets/Plugins/Android Folder. Then In Unity:
void OnGUI () {
string somestring = "foooooooooooOOooo";
AndroidJavaClass testClass = new AndroidJavaClass("moo.MyTestClass");
somestring = testClass.CallStatic<string>("Foo");
GUI.Label (new Rect (20, 20, 100, 20), somestring);
}
And I get an error:
JNI: Unable to find method id for 'Foo' (static)
UnityEngine.AndroidJavaObject:CallStatic(String, Object[])
Am I missing something to call my static method?
Thanks!

there are 2 problem as far as I can see:
you have to put your jar package to Assets/Plugins/Android/bin;
you will always get this error on your windows/mac editor, you have to run this on your android device;

Related

Unity Gear VR error on build

I.m trying to setup and build https://resources.samsungdevelopers.com/Gear_VR/030_Create_VR_App_or_Game_Using_a_Game_Engine/Exercise_2%3A_Create_a_Splash_Screen/Step_7%3A_Build_and_Run_the_Application
When I try and build the application it throws the following error:
Assets/Workshop/Scripts/TextureLoader.cs(114,31): error CS1105: `TextureLoader.GetFilesWithExtensions(this DirectoryInfo, params string[])': Extension methods must be declared static
// Gets the list of files in the directory by extention and filters for our specified ones (images)
public IEnumerable<FileInfo> GetFilesWithExtensions (this DirectoryInfo dir, params string[] extensions) {
IEnumerable<FileInfo> files = dir.GetFiles();
return files.Where(f => extensions.Contains(f.Extension));
}
public bool isFinishedLoadingFirstTexture() {
return mFinishedFirstTexture;
}
I have already changed it to a public static class in the header.
The class being static doesn't do much for the methods. You need to make your method static for the extensions to work!
public static IEnumerable<FileInfo> GetFilesWithExtensions (this DirectoryInfo dir, params string[] extensions) {
IEnumerable<FileInfo> files = dir.GetFiles();
return files.Where(f => extensions.Contains(f.Extension));
}
I wrote an extension method here if you need another example!
I order to make an extension method, the class must be public and static.
The function must be public and static too. You missed this part.
public static class TextureLoader
{
public static IEnumerable<FileInfo> GetFilesWithExtensions(this DirectoryInfo dir, params string[] extensions)
{
IEnumerable<FileInfo> files = dir.GetFiles();
return files.Where(f => extensions.Contains(f.Extension));
}
}
Modify your code this way, the error will disappear
private IEnumerable<FileInfo> GetFilesWithExtensions(DirectoryInfo dir, string[] extensions)
{
IEnumerable<FileInfo> files = dir.GetFiles();
return files.Where(f => extensions.Contains(f.Extension));
}

Calling simple java static method via JNI does not work, though c++ compiles and run it

Considering this Java class with the static method:
public class TestClass{
public string str;
public TestClass() {
str = "Test From Java";
}
public static String staticMethod() {
return "Test From Java";
}
}
I have written these lines of code in c++ file:
QAndroidJniObject str = QAndroidJniObject::callStaticObjectMethod(
"org/.../TestClass"
,"staticMethod"
,"(V)Ljava/lang/String;");
It seems everything is working but I don't know how can I use the str Object. I tried to convert it to a QString object using str.tostring() method but it always returns an empty string.
Why it does not work as expected? I've also tested ()Ljava/lang/String; for method signature but no success!
Thanks in advance.
You should specify the returned JNI type in <...> when calling the method :
QAndroidJniObject str = QAndroidJniObject::callStaticObjectMethod<jstring>(
"org/.../TestClass"
,"staticMethod");
QString string = str.toString();
Here there is no need to define the signature since your function has no argument.

Android, generate jni Header Files with javah , show error that can't find org.opencv.core.Mat

I just have an annoying problem with jni when i compile the native method in java class with javah to generate JNI header files.
If the class has used 3rd-party package, For example: org.opencv.core.Mat, then the javah will show the error that can't find the org.opencv.core.Mat class.
The OpenCV sample code as below:
package org.opencv.samples.fd;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
public class DetectionBasedTracker
{
public DetectionBasedTracker(String cascadeName, int minFaceSize) {
mNativeObj = nativeCreateObject(cascadeName, minFaceSize);
}
public void start() {
nativeStart(mNativeObj);
}
public void stop() {
nativeStop(mNativeObj);
}
public void setMinFaceSize(int size) {
nativeSetFaceSize(mNativeObj, size);
}
public void detect(Mat imageGray, MatOfRect faces) {
nativeDetect(mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr());
}
public void release() {
nativeDestroyObject(mNativeObj);
mNativeObj = 0;
}
private long mNativeObj = 0;
private static native long nativeCreateObject(String cascadeName, int minFaceSize);
private static native void nativeDestroyObject(long thiz);
private static native void nativeStart(long thiz);
private static native void nativeStop(long thiz);
private static native void nativeSetFaceSize(long thiz, int size);
private static native void nativeDetect(long thiz, long inputImage, long faces);
}
First, I used the command
javah -classpath bin/classes -bootclasspath (the directory of android.jar) -d jni (packageName + ClassName) , shows the error "can't find the org.opencv.core.Mat
Then I modified the command to
javah - classpath bin/classes - bootclasspath (the dir of android.jar) ; (the dir of the opencv lib jar) -d jni ..." ", this time it shows error
Exception
Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class
name: E:\Computer_Language\Java\soft_android\OpenCV-2.4.3-rc-android-sdk\OpenCV
-2.4.3-rc-android-sdk\sdk\java\bin\opencv library - 2.4.3.jar
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:177)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:68)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:509)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:335)
at com.sun.tools.javah.Main.main(Main.java:46)
I think, adding the directory of opencv lib in -bootclasspath is useful and neccessary. The error is because i just added two path in -bootclasspath or the format is something wrong?
Really confused.
Please give some help , thank u!
This is what I did:
1.Open Command line, type to the (project)/bin/classes:
2.type: javah -classpath (opencv4android sdk path)/java/bin/classes:(your project location)/bin/classes -jni (your java class file that contains the native library interfaces)
In my project. I did:
javah -classpath /home/zijun/Dev/adt/OpencvAndroid/sdk/java/bin/classes:/home/zijun/workspace/LocTM/bin/classes -jni com.brainport.loctm.TMatching
That works on Linux Ubuntu 12.04.02 64bit OS
I encountered the same problem too,it cost me half day.I just copy DetectionBasedTracker.java to my poject.I use Android Studio.When I use ExternalTools>javah to generate .h files,the console print cant find org.opencv.core.Mat.copying mat.java & matofRect.java to the directory DetectionBasedTracker.java exists just cause more java class cant be find.finally,I find this problem was caused by the import * clause in java file.and we seldom use java class in native method we defined.so I cut these java method and got this:
package cn.ntu.tonguefur.nativemethod;
public class DetectionBasedTracker{
private static native long nativeCreateObject(String cascadeName,int minFaceSize);
//Other native methods
private static native void nativeDetect(long thiz,long inputImage,long faces);
}
Now you can freely use javah command to generate .h
file.After that,add java methods and import packages you need.

Command Line Jar on Android Device

I currently have a compiled jar file that I would like to use on an android device. The code outputs to the command line using System.out.println().
How would I create a wrapper to grab the stdout and put it in a text view on an android device? Would I need to make any changes to the jar (I do have all the source code) to allow the wrapper?
Thanks in advance.
I think you'll need to make some changes. You can set standart output by calling
System.setOut(PrintStream out)
// Reassigns the "standard" output stream.
Where out is your own class that will print data to text view. See swing solution. Just set appending to text view and you can use this code.
Or just create one method
void log(String message);
where you appending text to your view. Then change all println() calls to this.
First you should consider that Android has a specific Java VM called Dalvik and not any jar can be ran under it.
If there's one point in your jar where output occurs, the best option would be to create a usual application with a TextView, include your jar to it's build path and replace a call to println() with output to it:
public void print(String msg) {
mTextView.setText(msg);
}
If there're many sources of output you could run you jar using java.lang.Process and use it's getInputStream() method to read printed messages:
public static final String XBOOT_CLASS_PATH = "-Xbootclasspath:/system/framework/core.jar"
public static final String CLASS_PATH = "-classpath /path/to/your/file.jar com.your.package.name"
...
Process p = new ProcessBuilder("dalvikvm", XBOOT_CLASS_PATH, CLASS_PATH).start();
BufferedReader reader = new BufferedReader (new InputStreamReader(p.getInputStream()));
String msg = reader.readLine();
if (msg != null) {
mTextView.setText(msg);
}
// Cleanup omitted for simplicity
If it's an executable jar file here is a working example
Add this simple executable HelloWorld jar file to your Android Project's build path
If the jar file doesn't have a package, then you will have to use Reflection to invoke methods in it.Other wise you can just import the class files and invoke the main method directly.(This example jar has a package "psae")
eg:
TextView tv = (TextView)findViewById(R.id.textv);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.setOut(ps);
String[] params = {"Aneesh","Joseph"};
psae.HelloWorld.main(params);
String output = baos.toString();
tv.setText(output)
If the jar file just has a default package, then you won't be able to import class files from that jar, and hence you will have to use Reflection to invoke the method.
TextView tv = (TextView)findViewById(R.id.textv);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.setOut(ps);
try {
//pick the entry class from the jar Manifest
//Main-Class: psae.HelloWorld
Class myClass = Class.forName("psae.HelloWorld");
//since this has a package, there is no need of reflection.This is just an example
//If the jar file had just a default package, the it would have been something like the below line (and this is where it would be useful)
//Class myClass = Class.forName("Main");
Method myMethod = myClass.getMethod("main", String[].class);
//parameters to the main method
String[] params = {"Aneesh","Joseph"};
myMethod.invoke(null, (Object) params);
String output = baos.toString();
tv.setText(output);
}
catch(Exception d)
{
tv.setText(d.toString());
}

Android - put an image name "package" throws compile time error

I am trying to put an image name "package.png" in my drawable folder. As soon as i paste them it into the folder it is throwing following error:
[2012-05-26 12:40:30 - MyApp] res/drawable-mdpi/package.png:0: error: invalid symbol: 'package'
But as soon as i rename to some other name, this image works fine. Any idea why this is happening and how i can fix this and have a drawable named "package".
you cant do that, as it is a Reserved word. just like...
break else new var
case finally return void
catch for switch while
continue function this with
default if throw
delete in try
do instanceof typeof
abstract enum int short
boolean export interface static
byte extends long super
char final native synchronized
class float package throws
const goto private transient
debugger implements protected volatile
double import public
null
true
false
Each resource having entry in java field name inside R.java class:
drawable\package.png -> R.drawable.package // while package is a reserved keyword in Java(mentioned above)

Categories

Resources