Android Question JavaObject or Reflection Code

walterf25

Expert
Licensed User
Hi all, does anyone know how to write this code using either JavaObject or Reflection libraries, maybe both are needed?

I'm not so good and don't really understand much how to use those two libraries, i've tried several things but none of them work

B4X:
        try {
            mCamera.setPreviewCallbackWithBuffer(callback);
            for (int i = 0; i < 16; i++)
                mCamera.addCallbackBuffer(new byte[1280*480*3/2]);
            mCamera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
I am able to create the callback Object like this
B4X:
    Dim callback As Object
    Dim r2 As JavaObject
    r2 = cam
    callback = r2.InitializeStatic("android.hardware.Camera$PreviewCallback")
i am using the CameraEx class example but i am trying to add the above code so that I can use this class in my EasyAR Library to be able to use a custom camera.

Thanks in advanced for any help or suggestions.

Walter
 

stevel05

Expert
Licensed User
If you already have the camera object and you just need to call the additional methods then this should work:

B4X:
Try
    Dim mCameraJO As JavaObject = mCamera
    mCameraJO.Runmethod("setPreviewCallbackWithBuffer",Array(callback))
    Dim i As Int
    For i = 0 To 15
        Dim BBuffer As Byte(1280*480*3/2)
        mCameraJO.Runmethod("addCallbackBuffer",Array(BBuffer))
    Next
    mCameraJO.Runmethod("startPreview",Null)
Catch
     Log(LastException)
End Try
 
Last edited:

walterf25

Expert
Licensed User
If you already have the camera object and you just need to call the additional methods then this should work:

B4X:
Try
    Dim mCameraJO As JavaObject = mCamera
    mCameraJO.Runmethod("setPreviewCallbackWithBuffer",Array(callback))
    Dim i As Int
    For i = 0 To 15
        Dim BBuffer As Byte(1280*480*3/2)
        mCameraJO.Runmethod("addCallbackBuffer",Array(BBuffer))
    Next
    mCameraJO.Runmethod("startPreview",Null)
Catch
     Log(LastException)
End Try
I am using CameraEx class and I pass the cam parameter from that class but i get the following error:
Error occurred on line: 94 (CameraExClass)
java.lang.RuntimeException: Method: setPreviewCallbackWithBuffer not found in: anywheresoftware.b4a.objects.CameraW
at anywheresoftware.b4j.object.JavaObject$MethodCache.getMethod(JavaObject.java:366)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:119)
at anywheresoftware.b4a.samples.camera.cameraexclass._startpreview2(cameraexclass.java:456)
at anywheresoftware.b4a.samples.camera.main._camera1_ready(main.java:704)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:735)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:360)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:260)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1058)
at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1013)
at anywheresoftware.b4a.samples.camera.cameraexclass._camera_ready(cameraexclass.java:711)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:735)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:360)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:260)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
at anywheresoftware.b4a.objects.CameraW$2$1.run(CameraW.java:139)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7037)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
** Activity (main) Pause, UserClosed = true **
 

stevel05

Expert
Licensed User
On looking at the rest of the Camera class, I'm not sure that your callback code with do what you are expecting, as there is no sub defined to call.

You may need to create a callback using :

B4X:
Callback = Jo.CreateEventFromUI("android.hardware.Camera$PreviewCallback","VidCallback",Null)
Then add a sub to handle it:


B4X:
Sub VidCallback_Event (MethodName As String, Args() As Object) As Object
    
End Sub
 

walterf25

Expert
Licensed User
On looking at the rest of the Camera class, I'm not sure that your callback code with do what you are expecting, as there is no sub defined to call.

You may need to create a callback using :

B4X:
Callback = Jo.CreateEventFromUI("android.hardware.Camera$PreviewCallback","VidCallback",Null)
Then add a sub to handle it:


B4X:
Sub VidCallback_Event (MethodName As String, Args() As Object) As Object
   
End Sub
I think we're getting somewhere, i tried your second suggestion and now I get the following:

java.lang.IllegalArgumentException: Expected receiver of type android.hardware.Camera, but got java.lang.Class<android.hardware.Camera>
Walter
 

stevel05

Expert
Licensed User
That's a new error from the creation of the callback,the original error will still be there.

It looks like the underlying camera object is not exposed in the library, I haven't used it so perhaps someone that has can help you further. Sorry to lead you on a wild goose chase.
 

stevel05

Expert
Licensed User
I've dug a little deeper into this and it's not clear to me how setting a callback buffer will allow accessing a custom camera, it doesn't appear to change any thing, only creates a callback sub which receives the preview frames in the buffers you provide when creating the callback.
 

stevel05

Expert
Licensed User
Or are you looking to display a custom sized preview?
 

walterf25

Expert
Licensed User
I've dug a little deeper into this and it's not clear to me how setting a callback buffer will allow accessing a custom camera, it doesn't appear to change any thing, only creates a callback sub which receives the preview frames in the buffers you provide when creating the callback.
So the reason for doing this, according to one of the EasyAR examples is that it improves preview efficiency and frame rate by allowing preview frame memory reuse.

Also because in the previewCallback callback function Erel is only exposing the data[] parameter in the signature and I also need the Camera parameter to be exposed in that same signature.
I am talking about this callback function
B4X:
 @Override
        public void onPreviewFrame(final byte[] data, final Camera camera)
Erel is only exposing the byte[] data paratemer and not the Camera parameter.

I think i'm just gonna have to write a separate class and wrap this as well, i was trying to avoid having to do this but it seems that for the sake of time I will just have to do that.

Walter
 

walterf25

Expert
Licensed User
You don't need the camera parameter. It will be always the same as the nativeCam global variable.
Oh I see, OK, i will give it a try tomorrow again.

Thanks,
Walter
 
Top