Android Tutorial Inline Java Code

stevel05

Expert
Licensed User
It should work, try this:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim NativeMe As JavaObject
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    NativeMe.InitializeContext  
    NativeMe.Runmethod("methodName",Array("String1","String2"))
   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

#If java

public void methodName(String s1,String s2){
    BA.Log(s1 + " " + s2);
}
#End If
 

giacomo-italy

Member
Licensed User
It depends on the complexity of the wrapped library. However you can add a reference to the library with #AdditionalJar attribute and then use inline Java code or JavaObject to access its API.

See this tutorial: Accesing third party Jar with #Additionaljar and JavaObject
Hello Erel,
I am one of many who would like to use opencv in B4A.
Do you think can I use the library opencv-2410.jar (file in opencv/build/java/... ) with #AdditionalJar,
and use inline Java code to access it?
For example embed Java code like the code shown below.
It is a java example (face detector) using methods of java opencv.

Is this correct?
Or am I astray?
Thanks a lot.

code:
------------------------------------------------------------------------------------------------------
package com.shekhar.facedetection;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.objdetect.CascadeClassifier;

public class FaceDetector {

public static void main(String[] args) {

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println("\nRunning FaceDetector");

CascadeClassifier faceDetector = new CascadeClassifier(FaceDetector.class.getResource("haarcascade_frontalface_alt.xml").getPath());
Mat image = Highgui
.imread(FaceDetector.class.getResource("shekhar.JPG").getPath());

MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);

System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

for (Rect rect : faceDetections.toArray()) {
Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
new Scalar(0, 255, 0));
}

String filename = "ouput.png";
System.out.println(String.format("Writing %s", filename));
Highgui.imwrite(filename, image);
}
}
-------------------------------------------------------------------------------------------
 

stu14t

Active Member
Licensed User
This seems an ideal solution for the Parse sdk, which has only been partially wrapped leaving some of the methods / objects not accessible (using the wrapper).

Is it OK to use the wrapper and inline java code to access the sdk together, I mean, they won't upset each other?
 

stu14t

Active Member
Licensed User
Parse provides a lot of example java code, how could this be used?

I would really like to see tutorials on In-line coding
 
Last edited:

giacomo-italy

Member
Licensed User
You can add any Java you like. However if you are not familiar with Java then it will be difficult to use this feature with non-simple code.
I'll start experimenting with OpenCV following this road.
Obviously I will start with the simplest things, of course also studying java.
I only ask for confirmation:
i have installed opencv 2.4.10 on Windows PC on which I use B4A,
then in the installation folder of opencv i reach the folder opencv/build/java/...,
and i find the file opencv-2410.jar,
this jar file that i incorporate with #AdditionalJar is the right file for working in opencv with java code ?
Thanks again.
 

giacomo-italy

Member
Licensed User
You need to check their documentation. Is this the jar you need to add to your Android project?
To be or not to be (..the right file..) that is the question!
It is possible that it is not, because is the file to build with Java in Windows.
Instead need I to find the jar file in the build of java in Android...?
I tried. But in the installation of opencv under Android, there is not a .jar file in the build folder.
Should be compiled opencv by the C++ with the Android SDK+NDK?
(The thing is complicated, and a little out of my league...)
What do you think about this?
Thanks
 

giacomo-italy

Member
Licensed User
Someone of goodwill, with more knowledge than me,
can think and give a tip on how to use OpenCV, maybe is best JavaCV (https://github.com/bytedeco/javacv),
with this new features of b4a (#Additionaljar and java code)?
Thanks

P.S.:
In https://github.com/bytedeco/javacv we can obtain JavaCV 0.10 binary archive:
  • javacv-0.10-bin.zip
The binary archive contains builds for Linux, Mac OS X, Windows, and Android
(it contain the files: javacv-android-x86.jar, opencv-android-x86.jar, ffmpeg-android-x86.jar etc..
as well as javacv-android-arm.jar, opencv-android-arm.jar, ffmpeg-android-arm.jar etc..).
The hamletic doubt about desired JAR files to use is dissolved? We can use these jar files?
The *-android-arm.jar or *-android-x86.jar files?
 

giacomo-italy

Member
Licensed User
I check the documentation about OpenCV for Android.
OpenCV for Android is designed as a standalone library APK.
(We can download OpenCV for Android from http://opencv.org/downloads.html and cliking on 'OpenCV for Android',
and downloading 'opencv-android-sdk' zip file).
We also can install the OpenCV Manager directly from Google Play store.
OpenCV Manager is an Android service targeted to manage OpenCV library binaries on end users devices.
It allows sharing the OpenCV dynamic libraries between applications on the same device.

But we need to include the OpenCV SDK as an Android library into our own Android project.
Then we can directly write the Java code and use opencv in our app.
(see the example 'How to acquire camera images using OpenCV' here:
http://developer.sonymobile.com/kno..._tutorial/get-started-with-opencv-on-android/ )

So after reading continuously a huge amount of information on the web,
my conclusion is that if there is a way to include the OpenCV SDK (designed as a standalone library APK: OpenCV_binary_pack_armv7a.apk, OpenCV_Manager_2.19_armv7a-neon-android8.apk ) as an b4a library into our own b4a project,
we will be able to use opencv, using java code that refers directly to the library, inside our b4a app.

Erel, then I ask you (as a last question on the subject, I promise) if we can
include the opencv sdk as the standalone library APK in B4A (and eventually how to include it)
and so we can write java code that refers directly to the library.

Thanks for your great patience in listening to us.
 

Siam

Active Member
Licensed User
hello,

how can i call a java class? like this:

B4X:
#If JAVA
import java.lang.Math;
import java.lang.Float;
public class AquaLib {
    public Float one(Float kh,Float co) {
    float x = (float) Math.round((7.90+Math.log(kh/(2.8*co))/Math.log(10))*100)/100;
    return x;
    }
    public Float two(Float kh,Float co) {
    float x = (float) Math.round((7.90+Math.log(kh/(2.8*co))/Math.log(10))*100)/100;
    return x;
    }   
    public Float tree(Float kh,Float co) {
    float x = (float) Math.round((7.90+Math.log(kh/(2.8*co))/Math.log(10))*100)/100;
    return x;
    }   
    public Float four(Float kh,Float co) {
    float x = (float) Math.round((7.90+Math.log(kh/(2.8*co))/Math.log(10))*100)/100;
    return x;
    }   
}
#end if
with :

B4X:
NativeMe.InitializeStatic("AquaLib")
Dim s As Float =  NativeMe.RunMethod("one",Array As Object(kh,co))
i get :

java.lang.ClassNotFoundException: java$lang$AquaLib

what is my error ?

lg

andy
 

mlc

Active Member
Licensed User
Hello,

If I test this code, the result is correct.

B4X:
Sub Process_Globals
    Private nativeMe As JavaObject
End Sub
Sub Service_Create
    nativeMe.InitializeContext
End Sub

Sub Service_Start (StartingIntent As Intent)
    Dim l As Long
    l = nativeMe.RunMethod("FreeSpace", Array(File.DirRootExternal))
    Log("l = " & l)

End Sub

#If JAVA
import java.io.File;
import android.content.Context;

public long FreeSpace(String Pathf) {
      File f = null;
      long v;
      boolean bool = false;
     
      try{
         // create new file
         f = new File(Pathf);
        
         // get number of unallocated bytes
         v = f.getFreeSpace();
        
         // true if the file path exists
         bool = f.exists();
        
         // if file exists
         if(bool)
         {
            // prints
            return v;
         }
         else
        {
         return 0;
         }
      }catch(Exception e){
         // if any error occurs       
       return 0;
     
      }
}

#End If
But if I copy exactly this code to my project (it is also a service), get this error:

line 40 = nativeMe.InitializeContext

B4X:
** Service (serverservice) Create **


Error occurred on line: 40 (serverservice)
java.lang.NoSuchFieldException: context


    at java.lang.ClassCache.findFieldByName(ClassCache.java:446)
    at java.lang.Class.getDeclaredField(Class.java:666)
    at anywheresoftware.b4j.object.JavaObject.InitializeContext(JavaObject.java:64)
    at mlc.wifitransfer.serverservice._service_create(serverservice.java:6308)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:302)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at mlc.wifitransfer.serverservice.onCreate(serverservice.java:48)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:1949)
    at android.app.ActivityThread.access$2500(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:989)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3691)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
    at dalvik.system.NativeStart.main(Native Method)
** Service (serverservice) Start **
Which could be the problem?

Thanks
 
Top