Can't access stream using Astra SDK Android

I am trying to access the color stream (actually any stream) from Orbbec Astra Embedded S using Astra SDK for Android. I am following the User Guide version 2.1.3 available on Orbec’s website. I call all of the methods exactly like in the documentation but FrameListener doesn’t return any frames.

After CAMERA and STORAGE permissions are granted, I initialize the camera in onCreate() :

private fun initializeAstraDevice() {

    val astraAndroidContext = AstraAndroidContext(this, object : AstraDeviceManagerListener {
        override fun onOpenAllDevicesCompleted(availableDevices: MutableIterable<UsbDevice>?) {
            appendLogText("onOpenAllDevicesCompleted")

    

            availableDevices?.forEach {
                Timber.d("Device id: ${it.deviceId}")
            }
        }

        override fun onOpenDeviceCompleted(p0: UsbDevice?, p1: Boolean) {
            appendLogText("onOpenDeviceCompleted")
        }

        override fun onNoDevice() {
            appendLogText("onNoDevice")
        }

        override fun onPermissionDenied(p0: UsbDevice?) {
            appendLogText("onPermissionDenied")
        }
    })

    with(astraAndroidContext) {
        initialize()
        openAllDevices()
    }
}

The camera is successfully initialized. Camera URI gets printed in the logs along with _AstraAndroidContext: Finished initialization message.

After the camera is initialized I try to start the stream:

 private fun startStream() {
    appendLogText("startStream")

    val streamSet = StreamSet.open()
    val streamReader = streamSet.createReader()
    val colorStream = ColorStream.get(streamReader)

    colorStream.availableModes.forEach { mode ->
        appendLogText("Mode: ${mode.width} ${mode.height}" )
    }

    streamReader.addFrameListener { streamReader, readerFrame ->
        appendLogText("COLOR FRAME!")
    }

    colorStream.start()

    thread {
        while (true) {
            Astra.update()
            try {
                Thread.sleep(30)
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
        }
    }
}

When code reaches the call to loop over available modes I get the following crash from Astra API (no frames are returned neither):

2021-07-29 13:03:00.573 9209-9209/com.payeye.test.orbbecstreamprovider E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.payeye.test.orbbecstreamprovider, PID: 9209
java.lang.UnsupportedOperationException: Invalid operation
    at com.orbbec.astra.ApiStatus.throwIfError(ApiStatus.java:76)
    at com.orbbec.astra.NativeMethods.checkStatus(NativeMethods.java:16)
    at com.orbbec.astra.ImageStream.ensureModes(ImageStream.java:23)
    at com.orbbec.astra.ImageStream.getAvailableModes(ImageStream.java:44)
    at com.payeye.test.orbbecstreamprovider.MainActivity.startStream(MainActivity.kt:73)
    at com.payeye.test.orbbecstreamprovider.MainActivity.onCreate$lambda-0(MainActivity.kt:30)
    at com.payeye.test.orbbecstreamprovider.MainActivity.lambda$f3om-rD6iVOCcnMjxqQGbL8mTzE(Unknown Source:0)
    at com.payeye.test.orbbecstreamprovider.-$$Lambda$MainActivity$f3om-rD6iVOCcnMjxqQGbL8mTzE.onClick(Unknown Source:2)
    at android.view.View.performClick(View.java:7335)
    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
    at android.view.View.performClickInternal(View.java:7304)
    at android.view.View.access$3600(View.java:815)
    at android.view.View$PerformClick.run(View.java:28155)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7711)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

Now, when I comment out the line to list the available modes, the frame listener doesn’t return any frames. The error message is not helpful.

Here is the whole code for MainActivity. Any tips would be highly appreciated.

class MainActivity : AppCompatActivity() {

      override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            Timber.plant(Timber.DebugTree())

             requestPermission()
              initializeAstraDevice()

              findViewById<Button>(R.id.button).setOnClickListener { startStream() }
}

private fun initializeAstraDevice() {

    val astraAndroidContext = AstraAndroidContext(this, object : AstraDeviceManagerListener {
        override fun onOpenAllDevicesCompleted(availableDevices: MutableIterable<UsbDevice>?) {
            appendLogText("onOpenAllDevicesCompleted")

            availableDevices?.forEach {
                Timber.d("Device id: ${it.deviceId}")
            }
        }

        override fun onOpenDeviceCompleted(p0: UsbDevice?, p1: Boolean) {
            appendLogText("onOpenDeviceCompleted")
        }

        override fun onNoDevice() {
            appendLogText("onNoDevice")
        }

        override fun onPermissionDenied(p0: UsbDevice?) {
            appendLogText("onPermissionDenied")
        }
    })

    with(astraAndroidContext) {
        initialize()
        openAllDevices()
    }
}


private fun startStream() {
    appendLogText("startStream")

    val streamSet = StreamSet.open()
    val streamReader = streamSet.createReader()
    val colorStream = ColorStream.get(streamReader)

    colorStream.availableModes.forEach { mode ->
        appendLogText("Mode: ${mode.width} ${mode.height}" )
    }

    streamReader.addFrameListener { streamReader, readerFrame ->
        appendLogText("COLOR FRAME!")
    }

    colorStream.start()

    thread {
        while (true) {
            Astra.update()
            try {
                Thread.sleep(30)
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
        }
    }
}


private fun appendLogText(text: String) {
    findViewById<TextView>(R.id.textView).text = StringBuilder()
        .append(findViewById<TextView>(R.id.textView).text)
        .append("\n")
        .append(text).toString()

    Timber.d(text)
}

private fun requestPermission() {
    val permissions = arrayOf(
        Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.CAMERA,
        Manifest.permission.READ_EXTERNAL_STORAGE
    )

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M)
        if (!hasPermissions(this, permissions))
            ActivityCompat.requestPermissions(this, permissions, 0);
}

private fun hasPermissions(context: Context, permissions: Array<String>): Boolean =
    permissions.all {
        ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
    }

}

1 Like

I doubt there are any Android support developers.

I had the same issue, using minSdkVersion 22(instead of 23) solved the issue for me.