Log in or register to post comments

has anybody managed to overlay Android Interface objects?

November 10, 2010 - 8:09am #1

I've implemented that Toast code from Kim and that works fine. Adapting it to work with buttons however is proving difficult.

The code compiles fine but no matter what I try I either get a blank screen popping up when a trackable has been detected or just nothing happens.

What I want it just to have a button on screen for a start.
Anyone managed this that could post a bit of code or provide any tips?

Thanks.

Re: has anybody managed to overlay Android Interface objects?

May 13, 2012 - 7:09pm #15

I don't think you want to inflate the view every time the handler is called. Instead, keep a reference to the overlay view from when you first inflated it and added it using addContentView.

- Kim

Re: has anybody managed to overlay Android Interface objects?

May 11, 2012 - 3:43pm #14

I tried to do the exact same things mentioned here. I'm working with the toasts example and just want the button to at least show up only when a trackable is found. But the button seems to show up every time.

Here is my ImageTargets.cpp

	if(state.getNumActiveTrackables() < 1){

            jclass javaClass = env->GetObjectClass(obj);
	    jmethodID AndroidObjectsMethod = env->GetMethodID(javaClass, "undisplayAndroidObjects", "()V");
            env->CallVoidMethod(obj, AndroidObjectsMethod);
	}

	else{
            jclass javaClass = env->GetObjectClass(obj);
            jmethodID AndroidObjectsMethod = env->GetMethodID(javaClass, "displayAndroidObjects", "()V");
            env->CallVoidMethod(obj, AndroidObjectsMethod);
	}
    // Did we find any trackables this frame?
    for(int tIdx = 0; tIdx < state.getNumActiveTrackables(); tIdx++)
    {
        // Get the trackable:
        const QCAR::Trackable* trackable = state.getActiveTrackable(tIdx);
        QCAR::Matrix44F modelViewMatrix =
            QCAR::Tool::convertPose2GLMatrix(trackable->getPose()); 

        // Choose the texture based on the target name:
        int textureIndex;
        if (strcmp(trackable->getName(), "chips") == 0)
...
..

Here is my ImageTargetsRenderer.java:

// A handler object for sending messages to the main activity thread
    public static Handler mainActivityHandler;
    
    // Called from native to display a message
    public void displayAndroidObjects()
    {
        // We use a handler because this thread cannot change the UI
    	Message message = new Message();
    	message.obj = "display";
        mainActivityHandler.sendMessage(message);
    }
    
    public void undisplayAndroidObjects()
    {
        // We use a handler because this thread cannot change the UI
    	Message message = new Message();
    	message.obj = "undisplay";
        mainActivityHandler.sendMessage(message);
    }

Here is my ImageTargets.java code

        super.onResume();
     	// Create a new handler for the renderer thread to use
        // This is necessary as only the main thread can make changes to the UI
        ImageTargetsRenderer.mainActivityHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
            	Context context = getApplicationContext();
            	String text = (String) msg.obj;
            	View overlayView = View.inflate(context, R.layout.interface_overlay, null);
            	Button mybutton = (Button) overlayView.findViewById(R.id.button1);
            	mybutton.setText(text);
            	if(text == "display")
            		mybutton.setVisibility(View.VISIBLE);
            	else if(text == "undisplay")
            		mybutton.setVisibility(View.INVISIBLE);
            	
            }
        };
...
...
//Adding overlay view
                    new Runnable() {
                        public void run()
                        {
                            // Hide the splash screen
                            mSplashScreenView.setVisibility(View.INVISIBLE);
                            
                            // Activate the renderer
                            mRenderer.mIsActive = true;
    
                            // Now add the GL surface view. It is important
                            // that the OpenGL ES surface view gets added
                            // BEFORE the camera is started and video
                            // background is configured.
                            addContentView(mGlView, new LayoutParams(
                                            LayoutParams.FILL_PARENT,
                                            LayoutParams.FILL_PARENT));
                            
                            // Add our UI overlay view on top of the glView
                            View overlayView = View.inflate(getApplicationContext(), R.layout.interface_overlay, null);
                            addContentView(overlayView, new LayoutParams(
                                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
                            
                            
                            // Start the camera:
                            updateApplicationStatus(APPSTATUS_CAMERA_RUNNING);
                        }
                };
...
...

Here is my overlay view xml:

<?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="invisible" >

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button" />

    </FrameLayout>

Can you explain what step am I doing wrong? Any help would be highly appreciated.

Thanks,
Parth

Re: has anybody managed to overlay Android Interface objects?

May 4, 2012 - 12:21pm #13

You're jumping on a very old thread, that activity has been replaced with a separate activity per sample (e.g. ImageTargets.java).

- Kim

Re: has anybody managed to overlay Android Interface objects?

May 3, 2012 - 1:25pm #12

Hello,

I'm sorry if the question is too naive, but I've just started working on QCAR as my final semester undergraduate project. Where do I find the QCARSampleActivity.java file?

Re: has anybody managed to overlay Android Interface objects?

November 12, 2010 - 6:03am #11

Yeah thanks for that.
I actually worked out how to do it and you just confirmed that I did it right.

I pretty much did something like this:

if(state.getNumActiveTrackables() < 1){

            javaClass = env->GetObjectClass(obj);
	    AndroidObjectsMethod = env->GetMethodID(javaClass, "undisplayAndroidObjects", "()V");

            env->CallVoidMethod(obj, AndroidObjectsMethod);

else{

            javaClass = env->GetObjectClass(obj);

            AndroidObjectsMethod = env->GetMethodID(javaClass, "displayAndroidObjects", "()V");

            env->CallVoidMethod(obj, AndroidObjectsMethod);

}

Re: has anybody managed to overlay Android Interface objects?

November 12, 2010 - 5:35am #10

Hmm, how are you actually getting the trackable? If you're adding this to the ImageTargets sample code, be aware that the following line only returns active (visible) trackables:

const QCAR::Trackable* trackable = state.getActiveTrackable(tIdx);

If you are using that, then you will never see the inactive states! You can query the State object for all known trackables (visible and not visible) using the getNumTrackables and getTrackable methods.

If this doesn't solve your problem, feel free to zip up your project and send it to me at

.

- Kim

Re: has anybody managed to overlay Android Interface objects?

November 12, 2010 - 3:52am #9

As of now I'm doing something like this in the renderFrame method of ImageTargets.cpp

switch (trackable->getStatus())

	{

	case QCAR::Trackable::UNKNOWN:

            javaClass = env->GetObjectClass(obj);

            displayAndroidObjectsMethod = env->GetMethodID(javaClass, "undisplayAndroidObjects", "()V");

            env->CallVoidMethod(obj, displayAndroidObjectsMethod);
	    androidObjectsDisplayed = 0;

		break;

	case QCAR::Trackable::UNDEFINED:

            javaClass = env->GetObjectClass(obj);

            displayAndroidObjectsMethod = env->GetMethodID(javaClass, "undisplayAndroidObjects", "()V");

            env->CallVoidMethod(obj, displayAndroidObjectsMethod);
	    androidObjectsDisplayed = 0;

		break;

	case QCAR::Trackable::NOT_FOUND:

            javaClass = env->GetObjectClass(obj);

            displayAndroidObjectsMethod = env->GetMethodID(javaClass, "undisplayAndroidObjects", "()V");

            env->CallVoidMethod(obj, displayAndroidObjectsMethod);
	    androidObjectsDisplayed = 0;

		break;

	case QCAR::Trackable::DETECTED:
	    //while (androidObjectsDisplayed = 0){

            javaClass = env->GetObjectClass(obj);

            displayAndroidObjectsMethod = env->GetMethodID(javaClass, "displayAndroidObjects", "()V");

            env->CallVoidMethod(obj, displayAndroidObjectsMethod);
	    androidObjectsDisplayed = 1;//}

		break;

	case QCAR::Trackable::TRACKED:
	    //while (androidObjectsDisplayed = 0){

            javaClass = env->GetObjectClass(obj);

            displayAndroidObjectsMethod = env->GetMethodID(javaClass, "displayAndroidObjects", "()V");

            env->CallVoidMethod(obj, displayAndroidObjectsMethod);
	    androidObjectsDisplayed = 1;//}

		break;

	default:

		break;

	}

I want to check the status every frame so that buttons displayed on the screen will appear when a target is in view and disappear when not.

Using the code above the program displays the button when the target is in view then stays if a target is in view or not.

Re: has anybody managed to overlay Android Interface objects?

November 12, 2010 - 12:59am #8

I have a sort of else if getStatus() = 0 then make the isTargetDetected variable equal to 0 and pass that to Java for it to turn the buttons visibility off.

I'm currently using a switch to test each status and I had trouble using the STATUS enum. The program just didn't recognise it.
(my code's probably just rubbish!)

EDIT: Was using the enums in the wrong way.

Re: has anybody managed to overlay Android Interface objects?

November 11, 2010 - 4:01pm #7

In fact, as I look at this closer, it doesn't seem that you ever make a call to Java when tracking is lost (unless that simply isn't included). How do you mark the point to hide your button? Setting button visibility in Java is an on-off switch, not something that needs to be set per frame, which is why I suggest having a method call for the status change.

Let me know if I'm simply misunderstanding your code!

- Kim

Re: has anybody managed to overlay Android Interface objects?

November 11, 2010 - 3:54pm #6

I wouldn't test the trackable status against a fixed number, try to use the STATUS enum in the Trackable.h file (located in build/include/QCAR). Play around with both DETECTED and TRACKED, to see which one suits your needs.

Also, depending on what you are doing, you may want to only make a call to Java when the status changes (not each frame). You might see better performance this way, especially if you are changing aspects of the Android UI in response to the data.

- Kim

Re: has anybody managed to overlay Android Interface objects?

November 11, 2010 - 5:27am #5

What I'm having trouble with is the method of determining if the trackable is visible or not. I'm using this in the cpp file

if (trackable->getStatus() == 6) {

	    jint isTargetDetected = 1;

            jclass javaClass = env->GetObjectClass(obj);

            jmethodID displayAndroidObjectsMethod = env->GetMethodID(javaClass, "displayAndroidObjects", "(I)V");

            env->CallVoidMethod(obj, displayAndroidObjectsMethod, isTargetDetected);
	}

Doesn't seem to work...

Re: has anybody managed to overlay Android Interface objects?

November 11, 2010 - 4:52am #4

How are you trying to hide the button when the trackable is no longer visible? You should be able to do it using something like this:

myButton.setVisibility(View.INVISIBLE);

Make sure you do that in the Handler, the mainActivityHandler if you copied my sample Toast code.

- Kim

Re: has anybody managed to overlay Android Interface objects?

November 11, 2010 - 3:17am #3

I was sure I tried that before.
I got it working this time although the button only appears when the trackable id detected and then it just stays.

At least I know how to get it on screen though.

Thanks for that Kim.

Re: has anybody managed to overlay Android Interface objects?

November 10, 2010 - 4:21pm #2

At what point are you adding your buttons to the view? I did something like this once, by adding a custom overlay view (with buttons) in the Shared project code, right after the glView is added via addContentView(). That's in the QCARSampleActivity.java file. It became something like this:

addContentView(mGlView, new LayoutParams(
    LayoutParams.FILL_PARENT,
    LayoutParams.FILL_PARENT));

// Add our UI overlay view on top of the glView
View overlayView = View.inflate(this, R.layout.interface_overlay, null);
addContentView(overlayView, new LayoutParams(
    LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

Try adding your buttons at that point, and let me know if it helps!

- Kim

Log in or register to post comments