How to build APK for TVico with Android Studio

We recently purchased a TVico and have downloaded and installed TVico.apk. Now we have the Nuitrack app and we can run it and see the camera output in the HDMI-connected monitor. So far so good.

I also created a sample C++ app using Android Studio 3.1.4 on Windows 10, and connecting the TVico to my laptop, I see it as a development target under Android Studio, and can run my sample app on it. Surprisingly painless up to now.

Now comes the fun part, creating our own Android apk that uses the Nuitrack libraries.

I downloaded Nuitrack SDK and see that it includes the includes files and shared libraries for Android in Nuitrack/lib/android.

Instead of reinventing the wheel, I am hoping that someone has created a sample Android Studio project with a sample app, that they could share here. Alternatively, are there instructions on how to create a sample project?

Thanks,
Aram

Hi afalsafi,

Please take a look at this tutorial on creating Android Studio project with Nuitrack: https://docs.google.com/document/d/1JAN1FJiSduS83RegoCrAUh1Qa3Gov0f_zCcHZ6AluSQ/edit?usp=sharing

1 Like

Hi olga.kuzminytkh,

Iā€™ve tried it but I keep getting the following error when I start the app.

09-24 09:22:47.745 2020-2020/? V/threaded_app: InputQueueCreated: 0xe545e160 ā€“ 0xe545e2a0
09-24 09:22:47.745 2020-2064/? V/threaded_app: APP_CMD_INPUT_CHANGED
Attaching input queue to looper
09-24 09:22:47.775 2020-2020/com.videro.viderobodytracker2 V/threaded_app: NativeWindowCreated: 0xe545e160 ā€“ 0xd4171808
09-24 09:22:47.775 2020-2064/com.videro.viderobodytracker2 V/threaded_app: APP_CMD_INIT_WINDOW
09-24 09:22:47.795 2020-2064/com.videro.viderobodytracker2 I/NUITRACK: Configuration file ( /storage/emulated/0/Android/data/com.tdv.nuitrack.sdk/files/nuitrack/nuitrack.config ) error: /storage/emulated/0/Android/data/com.tdv.nuitrack.sdk/files/nuitrack/nuitrack.config: cannot open file

--------- beginning of crash

09-24 09:22:47.795 2020-2064/com.videro.viderobodytracker2 A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 2064 (Thread-5)

Thanks Thomas

Hi GamerV,

Please advise did you install Nuitrack.apk on your TVico?
If yes, please check read permissions to the %NUITRACK_HOME%/data folder.

Thank you Olga for posting the guide. I was able to build an APK.

In CMakeLists.txt, I replaced the entire file contents with what was in your document, and as a result I had to comment out these lines from MainActivity.java:

// static {
// System.loadLibrary(ā€œnative-libā€);
// }
ā€¦
// TextView tv = (TextView) findViewById(R.id.sample_text);
// tv.setText(stringFromJNI());

Assuming this is correct, you may want to update the instructions.

Now I am able to load my app and run, but I get the socket error messages posted at the bottom of this reply. And the TVico screen turns black.

Thanks,
Aram

09-28 14:17:31.023 2385-2385/? I/art: Late-enabling -Xcheck:jni
09-28 14:17:31.357 2385-2385/com.example.nuitracktest2 I/InstantRun: starting instant run server: is main process
09-28 14:17:31.446 2385-2385/com.example.nuitracktest2 W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
09-28 14:17:31.512 2385-2385/com.example.nuitracktest2 I/art: Rejecting re-init on previously-failed class java.lang.Class<android.support.v4.view.ViewCompat$OnUnhandledKeyEventListenerWrapper>
09-28 14:17:31.513 2385-2385/com.example.nuitracktest2 I/art: Rejecting re-init on previously-failed class java.lang.Class<android.support.v4.view.ViewCompat$OnUnhandledKeyEventListenerWrapper>
09-28 14:17:31.713 2385-2428/com.example.nuitracktest2 D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
09-28 14:17:31.716 2385-2385/com.example.nuitracktest2 D/Atlas: Validating mapā€¦
09-28 14:17:31.716 2385-2385/com.example.nuitracktest2 W/Atlas: Pointer 0x0, not in getPreloadedDrawables?
Pointer 0x0, not in getPreloadedDrawables?
09-28 14:17:31.768 2385-2428/com.example.nuitracktest2 I/mali_so: [File] : hardware/arm/maliT760/driver/product/base/src/mali_base_kbase.c; [Line] : 780; [Func] : base_context_deal_with_version_affairs_rk_ext;
arm_release_ver of this mali_so is ā€˜r6p0-02rel0ā€™, rk_so_ver is ā€˜11@0ā€™, built at ā€˜16:20:19ā€™ for 3288w, on ā€˜Aug 1 2016ā€™.
[File] : hardware/arm/maliT760/driver/product/base/src/mali_base_kbase.c; [Line] : 807; [Func] : base_context_deal_with_version_affairs_rk_ext;
mali_ver_property has been set to ā€˜r6p0-02rel0-13-11@0ā€™, to return.
09-28 14:17:31.770 2385-2428/com.example.nuitracktest2 I/OpenGLRenderer: Initialized EGL, version 1.4
09-28 14:17:31.778 2385-2428/com.example.nuitracktest2 D/OpenGLRenderer: Enabling debug mode 0
09-28 14:17:31.975 2385-2385/com.example.nuitracktest2 W/art: Before Android 4.1, method int android.support.v7.widget.DropDownListView.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
09-28 14:17:32.113 2385-2385/com.example.nuitracktest2 W/linker: libnuitrack_gl_sample.so: unused DT entry: type 0x6ffffffe arg 0x3e7fc
libnuitrack_gl_sample.so: unused DT entry: type 0x6fffffff arg 0x1
09-28 14:17:32.120 2385-2385/com.example.nuitracktest2 V/threaded_app: Creating: 0xb7adfd30
09-28 14:17:32.120 2385-2443/com.example.nuitracktest2 V/threaded_app: Config: mcc=0 mnc=0 lang=en cnt=US orien=2 touch=1 dens=160 keys=2 nav=1 keysHid=1 navHid=0 sdk=22 size=4 long=2 modetype=1 modenight=1
09-28 14:17:32.120 2385-2385/com.example.nuitracktest2 V/threaded_app: Start: 0xb7adfd30
09-28 14:17:32.120 2385-2443/com.example.nuitracktest2 V/threaded_app: activityState=10
09-28 14:17:32.121 2385-2385/com.example.nuitracktest2 V/threaded_app: Resume: 0xb7adfd30
09-28 14:17:32.121 2385-2443/com.example.nuitracktest2 V/threaded_app: activityState=11
09-28 14:17:32.124 2385-2385/com.example.nuitracktest2 V/threaded_app: InputQueueCreated: 0xb7adfd30 ā€“ 0xb7ae0a68
09-28 14:17:32.124 2385-2443/com.example.nuitracktest2 V/threaded_app: APP_CMD_INPUT_CHANGED
09-28 14:17:32.125 2385-2443/com.example.nuitracktest2 V/threaded_app: Attaching input queue to looper
09-28 14:17:32.150 2385-2385/com.example.nuitracktest2 V/threaded_app: NativeWindowCreated: 0xb7adfd30 ā€“ 0xb7ae1890
09-28 14:17:32.151 2385-2443/com.example.nuitracktest2 V/threaded_app: APP_CMD_INIT_WINDOW
09-28 14:17:32.166 2385-2385/com.example.nuitracktest2 V/threaded_app: WindowFocusChanged: 0xb7adfd30 ā€“ 1
09-28 14:17:32.179 2385-2443/com.example.nuitracktest2 I/NUITRACK: virtual void tdv::nuitrack::middleware::BluetoothDepthProvider::init(const ptree&)
09-28 14:17:32.180 2385-2445/com.example.nuitracktest2 I/NUITRACK: void tdv::nuitrack::middleware::LinuxBluetoothProxy::workFunc(const ptree&)
09-28 14:17:32.181 2385-2443/com.example.nuitracktest2 I/NUITRACK: virtual void tdv::nuitrack::middleware::BluetoothDepthProvider::subscribeImpl()
virtual void tdv::nuitrack::middleware::LinuxBluetoothProxy::start(int)
virtual void tdv::nuitrack::middleware::LinuxBluetoothProxy::start(int)
virtual void tdv::nuitrack::middleware::BluetoothSegmentation::init(const ptree&)
09-28 14:17:32.182 2385-2443/com.example.nuitracktest2 I/NUITRACK: virtual void tdv::nuitrack::middleware::BluetoothSegmentation::subscribeImpl()
virtual void tdv::nuitrack::middleware::LinuxBluetoothProxy::start(int)
virtual void tdv::nuitrack::middleware::BluetoothSkeletonization::init(const ptree&)
09-28 14:17:32.183 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to updater
09-28 14:17:32.184 2385-2443/com.example.nuitracktest2 I/NUITRACK: _isProxyAndroidInstance: false
virtual void tdv::nuitrack::middleware::LinuxBluetoothProxy::start(int)
09-28 14:17:32.185 2385-2443/com.example.nuitracktest2 I/NUITRACK: virtual void tdv::nuitrack::middleware::BluetoothSkeletonization::subscribeImpl()
virtual void tdv::nuitrack::middleware::LinuxBluetoothProxy::start(int)
virtual void tdv::nuitrack::middleware::BluetoothHandTracker::init(const ptree&)
virtual void tdv::nuitrack::middleware::BluetoothHandTracker::subscribeImpl()
virtual void tdv::nuitrack::middleware::LinuxBluetoothProxy::start(int)
virtual void tdv::nuitrack::middleware::BluetoothGestureRecognizer::init(const ptree&)
virtual void tdv::nuitrack::middleware::BluetoothGestureRecognizer::subscribeImpl()
virtual void tdv::nuitrack::middleware::LinuxBluetoothProxy::start(int)
09-28 14:17:33.183 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:34.184 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:35.184 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:36.185 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:37.185 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:38.185 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:39.186 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:40.186 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:41.187 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:42.187 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:43.188 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:44.188 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:45.189 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:46.189 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:47.189 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:48.190 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:49.190 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:50.191 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:51.191 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:52.192 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:53.192 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:54.192 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:55.193 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:56.193 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:57.194 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:58.194 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:17:59.195 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:00.195 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:01.195 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:02.196 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:03.196 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:04.197 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:05.197 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:06.197 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:07.198 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:08.198 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:09.199 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:10.199 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).
09-28 14:18:11.200 2385-2445/com.example.nuitracktest2 I/NUITRACK: Canā€™t connect to nuitrack.local.socket. Retry after 1s. (Number of interruptions = 0).

Please run Nuitrack app before you run your app. Nuitrack app starts Android service with the server, and this service should run in the background when you use your apps on TVico.

As an alternative, you can install Nuitrack.apk instead of TVico.apk on TVico.

Thanks Olga. I have also followed the set of instructions and I get the screen where I can see the skeleton and my movement with a blue and red dot where my hands are pointing when running the app.

Iā€™ve done some android development before with android studio and I am puzzled as to why when the code runs it sets my content view to the black/gray screen with image of my skeleton and instead of the content view set of my main activity. I guess my question is what exactly does the code do in my main activity where I donā€™t see a basic android white screen with a hello image that i set for my layout.activity_main. Thank you for all your help, much appreciated.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

    // Example of a call to a native method
    //TextView tv = (TextView) findViewById(R.id.sample_text);
    //tv.setText(stringFromJNI());

    Nuitrack.init(this, new Nuitrack.NuitrackCallback()
    {
        public void onInitSuccess(Context context)
        {
            Intent intent = new Intent(context, NativeActivity.class);
            startActivity(intent);
            finish();
        }
        public void onInitFailure(int errorId) {}
    });

}

Hi donAim,

After Nuitrack is initialized, NativeActivity is called, as a result you see the depth map with the skeleton.