0

i am trying to make a port of the TensorFlow Speech Command Example and send the result to my vr Unity3d game. first i did some research on how to make a service background with android and unity and i managed to do that successfully to make the speech command example work separately from unity. the only thing i am stuck with now is that the TensorInferenceInference Java class which is the boss here in recognizing words input...is not found on my apk unity build and the log would be like this:

 (Filename: D Line: 0)
06-08 21:47:40.212 4729-4729/com.usn.unityplugin V/SpeechRecognitionService: Reading labels from: conv_actions_labels.txt
06-08 21:47:40.216 4729-4729/com.usn.unityplugin D/AndroidRuntime: Shutting down VM
06-08 21:47:40.231 4729-4729/com.usn.unityplugin E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.usn.unityplugin, PID: 4729
    java.lang.Error: FATAL EXCEPTION [main]
    Unity version     : 2017.1.1f1
    Device model      : samsung SM-G610F
    Device fingerprint: samsung/on7xeltedd/on7xelte:7.0/NRD90M/G610FDDU1BRD1:user/release-keys

    Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lorg/tensorflow/contrib/android/TensorFlowInferenceInterface;
        at app.test.pluginservice.SpeechRecognitionService.onCreate(SpeechRecognitionService.java:107)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3534)
        at android.app.ActivityThread.-wrap6(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1732)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
     **Caused by: java.lang.ClassNotFoundException: Didn't find class "org.tensorflow.contrib.android.TensorFlowInferenceInterface" on path: DexPathList[[zip file "/data/app/com.usn.unityplugin-2/base.apk"],nativeLibraryDirectories=[/data/app/com.usn.unityplugin-2/lib/arm, /data/app/com.usn.unityplugin-2/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]**
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at app.test.pluginservice.SpeechRecognitionService.onCreate(SpeechRecognitionService.java:107) 
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3534) 
        at android.app.ActivityThread.-wrap6(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1732) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6776) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408) 

i am using TensorFlow Model (Kaldi) with float[] as input and "string label" as output and i want to make unity receive this string value every couple of seconds so that i thought it would be good if i get my hands on the example on android and porting it to unity as AAR plugin which is what i did and what brought me to ask Question about this error above.

btw i am newbie in android development :) just game developer and i need to make this work and receive the results labels from unity.

here's C# Code:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ImportJava : MonoBehaviour
{

    AndroidJavaClass unityClass;
    AndroidJavaObject unityActivity;
    AndroidJavaObject TestTensorObject;
    AndroidJavaClass customClass;
    public Text txt;
    // Use this for initialization

    void Start()
    {
        //Replace with your full package name
        Debug.Log("Getting JAVA DATA");
        sendActivityReference("app.test.pluginservice.TestServiceActivity");
        startService();

    }
    void Update()
    {
        if (Time.frameCount % 30 == 0)
        {
             //GetString();
        }
    }
    private void GetString()
    {
        var str = customClass.CallStatic<string>("GetStr");
        Debug.Log(" +++GetString()++++ " + str);
    }

    private void GetDate()
    {

        string str = customClass.CallStatic<string>("getTestData");
        Debug.Log("unityActivity.Get<string>(getTestData);" + str);
    }

    void sendActivityReference(string packageName)
    {
        Debug.Log("entered sendActivityReference");
        unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");

        customClass = new AndroidJavaClass(packageName);

        customClass.CallStatic("receiveActivityInstance", unityActivity);


    }

    void startService()
    {
        Debug.Log(" entered startService");

       customClass.CallStatic("StartServiceTestServiceActivityClass");


    }
}

and the Java Service Code:

package app.test.pluginservice;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import java.util.Timer;
import java.util.TimerTask;

public class TestServiceActivity {

    static String resultString = "EmptyCommand";


    static Activity myActivity;

    // Called From C# to get the Activity Instance
    public static void receiveActivityInstance(Activity tempActivity) {
        myActivity = tempActivity;
    }

    public static void StartServiceTestServiceActivityClass() {
        myActivity.startService(new Intent(myActivity, SpeechRecognitionService.class));
    }

    public static String GetStr() {

        resultString = SpeechRecognitionService.getmInstance().getRecognitionOutput();
        Log.d("wat?", "GetStr: " + resultString);

        return resultString;
    }

    public static void stopService() {
        SpeechRecognitionService.getmInstance().stopService();
    }
}
  • You need to post both the Java and C# code. – Programmer Jun 08 '18 at 19:40
  • Edited ^_^ it's my first time on stackoverflow :d – Nadir Pervez Jun 08 '18 at 19:43
  • No problem. Two things: 1.Where did you put the .jar plugin in your Unity project? 2.Can you put a simple `int` function that returns `2` in your Java plugin then call it from C# and see if it works? – Programmer Jun 08 '18 at 19:47
  • first i did a small prototype about this and it's AAR plugin in /Plugins/Android/speechAAR.aar – Nadir Pervez Jun 08 '18 at 19:48
  • Did the prototype work? – Programmer Jun 08 '18 at 19:49
  • it was a success but i couldn't manage to make tensorflowInference which is a java tensorflow class from working on unity activity – Nadir Pervez Jun 08 '18 at 19:49
  • it was like not found in my module android project but it was there with name libtensorflow_inference.so – Nadir Pervez Jun 08 '18 at 19:53
  • the path in my android project was /pluginservice/src/main/jniLibs – Nadir Pervez Jun 08 '18 at 19:56
  • checked also the apk structure after unity build and it was there inside Lib folder (when you open the apk with winrar) – Nadir Pervez Jun 08 '18 at 19:57
  • What library did you use for the tensorflow? What's the name and the extension? – Programmer Jun 08 '18 at 19:57
  • you can see the details from here bro [link](https://github.com/nadir500/SpeechCommandTensorflowAarPlugin) – Nadir Pervez Jun 08 '18 at 20:00
  • it's the official one from google [link](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android) – Nadir Pervez Jun 08 '18 at 20:01
  • they got *.so library you can download it when making gradle sync and you got TensorFlowInferenceInference.java class to make interactions between .so files and the model with java code. – Nadir Pervez Jun 08 '18 at 20:03
  • Also copy the `libtensorflow_inference.so` to the `/Plugins/Android/` folder. Build and run it then tell me if the error has changed. – Programmer Jun 08 '18 at 20:09
  • ok i'll do it :) – Nadir Pervez Jun 08 '18 at 20:11
  • look :v the funny thing is that when i dragged the libtensorflow_inference.so file to unity and trying to build it, the engine made this error: Duplicate file(s) in apk: 'D:\Unity Projects\TestTensorAndroid\Temp\StagingArea\android-libraries\pluginservice-debug\libs'...it's like the lib still in the apk but the app can't manage to find it – Nadir Pervez Jun 08 '18 at 20:17
  • same problem bro :/ tried to do it...deleted '.so' files from the android project and moved it to 'plugin/android' in unity but the same error keep going plus app crash – Nadir Pervez Jun 08 '18 at 20:25
  • After deleting it and moving it to the Unity project, which error? The one in your question or comment? – Programmer Jun 08 '18 at 20:28
  • the question ^_^ – Nadir Pervez Jun 08 '18 at 20:29
  • I carefully read the error again and it looks like it's looking for `TensorFlowInferenceInterface`. It can't find it. The plugin you [linked](https://github.com/nadir500/SpeechCommandTensorflowAarPlugin) doesn't even have it. [This](https://github.com/baidu-research/tensorflow-allreduce) one does. Maybe you should be using that – Programmer Jun 08 '18 at 21:01
  • i will give it a shot – Nadir Pervez Jun 08 '18 at 21:11

0 Answers0