• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Writing an Android Java plug-in for Unity3D

When using WebCamTexture in Unity3D (and then building and deploying to Android) the camera does not focus correctly, which becomes a big problem when developing apps that scan QR codes or perform OCR.

Currently, there seems to be no way to focus the device camera on Android from within Unity3D, but there are a few posts that suggest you can force Android auto-focus by creating an Android Java plug-in for Unity3D which sets auto-focus and then calls it from within a C# script of your Unity3D project.

Inspired by the existing posts, I set out to do exactly this in Android Studio and put an end to it once and for all! (twice actually -- once with Blank Activity and once with No Activity. Which one should be used for plug-in development?)

What I have so far is as follows, though it does not seem to be working at all. I wonder if yould would take a look and make suggestions, or better still give it a try and help me understand what I am missing or doing wrong. It is very easy to follow what I have done...

I would very much welcome and appreciate any help or hint, as this has consumed me for a while now. I have also included little questions in my code comments if you would also address those please.

I wrote the following code in Android Studio, while following this tutorial:


C#:
package com.example.unityplugin;

import java.util.List;
import android.hardware.Camera;
import android.util.Log;

public class OcrFocusPluginClass
{
    public static void EnableAutofocus()
    {
        System.out.println("Entered the method...");

        Camera camera = Camera.open();
        Camera.Parameters parameters = camera.getParameters();

        List<String> focusModes = parameters.getSupportedFocusModes();

        if ( focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO) )
        {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

            Log.i("app", "camera focus set");
        }

        camera.setParameters(parameters);
    }
}

// I have tried all 3 modes:
// FOCUS_MODE_AUTO
// FOCUS_MODE_CONTINUOUS_PICTURE
// FOCUS_MODE_CONTINUOUS_VIDEO

The following is the C# script in my Unity3D project that calls the built library; the outcome of building the above in Android Studio and making a Module out of it:

C#:
public class OcrAndroidFocus : MonoBehaviour
    {
        public static void Focus()
        {
            #if UNITY_ANDROID
            try
            {
                using ( AndroidJavaObject androidJavaObject = new AndroidJavaObject("com.example.unityplugin.OcrFocusPluginClass") ) // AndroidJavaObject or AndroidJavaClass ?
                {
                    if (androidJavaObject != null)
                    {
                        androidJavaObject.CallStatic("EnableAutofocus"); // .Call or .CallStatic ?  Do I also need <void> return type ?
                        Debug.Log("androidJavaObject != null success!");
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }
            #endif
        }
    }

In another Unity3D C# script in the same name space, I have the following method that creates the texture and calls the jar file's method:

C#:
public void StartWebcam()
        {
            if (!_isRunning)
            {
                _webCamTexture = new WebCamTexture();
                gameObject.GetComponent<RawImage>().texture = _webCamTexture;

                OcrAndroidFocus.Focus(); // Do I need to cancel this at some point?

                _webCamTexture.Play();
                _isRunning = true;
            }
        }

Of course, I have the following in my AndroidManifest.xml

C#:
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-feature android:glEsVersion='0x00020000'/>
    <uses-feature android:name="android.hardware.camera" android:required="true"/>
    <uses-feature android:name="android.hardware.camera.autofocus" android:required="true"/>
    <uses-feature android:name="android.hardware.camera.front" android:required="true"/>

Although, at this point, I must admit that this manifest exists (from before) in my Unity3D project's Assets/Plugins/Android though the tutorial (the link I put in the beginning of this post) told me to place the resulting classes.jar file and AndroidManifest.xml files in Assets/Plugins/Android/libs which I have done so. Is this right?

So... I build my Unity3D app for Android but when I start it on a Galaxy tablet, I notice nothing different...

Could someone please test this and see perhaps I missed a step or maybe I am doing something wrong? Please let me know if I can provide more info in this post to facilitate a solution at the end. It seems that from the time of this post/petition and this petition/post which go as far back as April 2014, the WebCamTexture is still problematic on Android.


Many thanks in advance,
 
Thanks for your reply.

I have no emulator installed.

I see your point about losing debug output, but is it not possible to see the output of "System.out.println" and "Log"?

For example, in this little program below, where and how can I fish for these two "Entered" strings?

When I include a "Debug.Log" in my Unity3D C# code, I can see it using adb logcat in my Terminal, but I do not know where/how to see debug output that put in my Android code...

My Java code in Android gets built into a Module/Library and then used/called in Unity3D, so how can I see the debug messages like the two below?

Code:
public class PluginClass
{
    public static void Enable()
    {
        System.out.println("Entered the method...");

        blah...

        if ( blah... )
        {
            Log.e("app", "Entered if statement...");
        }

        blah...
    }
}
 
Upvote 0

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones