Log in or register to post comments

Overlaying Android Interface Objects

October 13, 2010 - 11:31am #1

Hello everybody,

I' am fairly new to developing Apps for Android, so please excuse my question if it is to simple.
I like to develop an AR App in whitch the user gets information depending on the tracked image. Therefore I don't nees any 3D-Model or somthing like that. Furthermore the user should be able to interact whith the overlaying interface (for example a button for more information).
The hole handling of the Data-Logic (getting the right information, handle touch, etc) should done in java.

Do anybody have an idea?

Thanks for your help

Overlaying Android Interface Objects

February 24, 2013 - 8:20am #32

thanx, that will be usefull for me.. but, i mean the image is not as 3d object, but an image that overlay the camera..

Overlaying Android Interface Objects

February 24, 2013 - 7:56am #31

Overlaying Android Interface Objects

February 23, 2013 - 10:53pm #30

hey.. is it possible to overlay an image instead of text? i'am new in native programming, can someone tell me how to do it?

Overlaying Android Interface Objects

February 1, 2013 - 11:33pm #29

may i kno wat u did???????

i need it...plz

Overlaying Android Interface Objects

September 28, 2012 - 1:48am #28

yes i did it. thank you~

Overlaying Android Interface Objects

July 23, 2012 - 2:31pm #27

Hello,

After getting the target name there are a few options to render that name onto a texture on a 3D plane over the target. Please see http://stackoverflow.com/questions/1339136/draw-text-in-opengl-es-android for some options for doing this.

Thank you,

-Peter

Overlaying Android Interface Objects

July 20, 2012 - 4:13pm #26

yes i want select for the message based on the name and every name have a different text

Overlaying Android Interface Objects

July 18, 2012 - 3:57pm #25

Do you want to present the name?

trackable->getName()

or you can select for the message based on the name. Is this what you're asking?

Overlaying Android Interface Objects

July 18, 2012 - 2:20am #24

how to chnge if every marker have a different text?

Overlaying Android Interface Objects

July 8, 2012 - 1:01am #23

thx 

Overlaying Android Interface Objects

June 27, 2012 - 4:09pm #22

Hi check

 

You need to add this lines:

if (state.getNumActiveTrackables() == 0)

{

    lastTrackableId = -1;

}

 

you must add the lines to get this:

 

    // Did we find any trackables this frame?

    if (state.getNumActiveTrackables() == 0)

{

    lastTrackableId = -1;

}

    for(int tIdx = 0; tIdx < state.getNumActiveTrackables(); tIdx++) 

....

 

I hope that helps

Re: Overlaying Android Interface Objects

June 15, 2012 - 3:11am #21
ksiva wrote:

This is possible but somewhat tricky. If you're new to Android, you may want to start by creating the user interface without the Augmented Reality SDK, to learn how the Android UI works.

Then, I suggest copying the ImageTargets sample project as a starting point for an AR application. Add your custom user interface elements to it.

There are a few steps required for making changes to the Android UI when a trackable becomes active. Let's start with the native code. Here is a simple example for passing a message from native to Java when a trackable first comes into view. Add this to ImageTargets.cpp:

int lastTrackableId = -1;

JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv* env, jobject obj)
{
    ...
    
    // 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);
        
        // Compare this trackable's id to a globally stored id
        // If this is a new trackable, find the displayMessage java method and
        // call it with the trackable's name
        if (trackable->getId() != lastTrackableId) {
            jstring js = env->NewStringUTF(trackable->getName());
            jclass javaClass = env->GetObjectClass(obj);
            jmethodID method = env->GetMethodID(javaClass, "displayMessage", "(Ljava/lang/String;)V");
            env->CallVoidMethod(obj, method, js);
            lastTrackableId = trackable->getId();
        }
        
        ...
    }
    
    ...
}

Next, here's the java method that the native code is calling. Add this to the ImageTargetsRenderer class in 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 displayMessage(String text)
    {
        // We use a handler because this thread cannot change the UI
    	Message message = new Message();
    	message.obj = text;
        mainActivityHandler.sendMessage(message);
    }

Finally, you need to create and register this handler in the ImageTargets java class. The onResume method is a good place to do this:

    protected void onResume()
    {
        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;
            	int duration = Toast.LENGTH_SHORT;
            	Toast toast = Toast.makeText(context, text, duration);
            	toast.show();
            }
        };
    }

This example should display a temporary message on the screen when a new target comes into view (either the stones or chips targets that the ImageTargets sample uses). Hopefully this will get you started.

- Kim

The above code works fine first time. if i compare the image for second time, nothing will come... can u help me to solve the problem.

Re: Overlaying Android Interface Objects

December 23, 2011 - 7:35pm #20

Thanks a lot Kim,
Issue has been resolved when rebuild the native code.

-Arshad

Re: Overlaying Android Interface Objects

December 23, 2011 - 6:20pm #19

Make sure you are rebuilding the native code using "ndk-build" when you make changes. Then refresh the project in Eclipse (right-click in the Package Explorer and choose Refresh).

Try adding a LOG message after calling CallVoidMethod in native. Can you see it in the log file when you look at the target?

- Kim

Re: Overlaying Android Interface Objects

December 22, 2011 - 9:17pm #18

Hello Kim, sorry to bother you, I am new to AR development. I tried to run the sample of ImageTargets as you described to display the message on trackables (Chips & Stones) but nothing happened. when I tried to debug to see whether Handler method is being called in onResume(), it is not being called. I tried a lot but unable to resolve the issue. Could you help me?
thanks in advance!

Re: Overlaying Android Interface Objects

November 15, 2011 - 8:02pm #17

Thanks Kim, it works great. :-)

Re: Overlaying Android Interface Objects

November 15, 2011 - 9:28am #16

Try resetting the lastTrackableId variable when there are no trackables in view:

if (state.getNumActiveTrackables() == 0)
{
    lastTrackableId = -1;
}

- Kim

Re: Overlaying Android Interface Objects

November 15, 2011 - 12:31am #15

Hi Kim,

The given code detects the trackable image only for one time, if i put the camera again to detect the image, it does nothing. I have tried, but could resolve the issue.

Please help me.

Regards

Rahul

Re: Overlaying Android Interface Objects

November 14, 2011 - 2:25am #14

Hi Abhishek
Pass parameters like this:-Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv * env, jobject obj)

Rahul

Re: Overlaying Android Interface Objects

August 25, 2011 - 2:31pm #13

I am using the latest sdk of qualcomm and i am having problem doing the changes you mentioned. After i did changes in ImageTarget.cpp file i ran into terminal and ran ndk-build but it wouldnt let me compile. I get the following error :-

Invalid attribute name:
package
Compile++ arm : ImageTargets /Users/abhishek/softwares/qcar-android-1-0-6/samples/ImageTargets/jni/ImageTargets.cpp: In function 'void Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv*, _jobject*)':
/Users/abhishek/softwares/qcar-android-1-0-6/samples/ImageTargets/jni/ImageTargets.cpp:461: error: 'state' was not declared in this scope
make: *** [/Users/abhishek/softwares/qcar-android-1-0-6/samples/ImageTargets/obj/local/armeabi/objs/ImageTargets/ImageTargets.o] Error 1
and i dont know what it is for?

All i want to do i start an intent when trackable is found

Re: Overlaying Android Interface Objects

August 16, 2011 - 11:12pm #12
ksiva wrote:
            env->CallObjectMethod(obj, method, js);


- Kim

Actually, it should be CallVoidMethod . ;)

Re: Overlaying Android Interface Objects

January 6, 2011 - 6:09am #11

No, the handler gets created in the onResume method, but isn't run until someone sends it a message.

Here's the issue: we have two threads in play, the UIThread and the GLThread. You can only make changes to the Android UI in the UIThread, and you can only render content via OpenGL in the GLThread. The onDrawFrame method in the Renderer class is run on the GLThread, which means that your native renderFrame method is also run on the GLThread.

To make changes to the Android UI from the GLThread, you place a message in the UIThread's message queue via a Handler. That way, the next time the UIThread gets focus your messages are processed and the Android UI is updated.

In short, the Handler just represents a callback method, allowing one thread to call methods on another thread in an asynchronous way.

- Kim

Re: Overlaying Android Interface Objects

January 6, 2011 - 4:53am #10

Is there another way of doing this?
Handlers in the onResume method get ran once when the application starts. Any way around that?

Re: Overlaying Android Interface Objects

November 29, 2010 - 3:53am #9

OK, that's what I have done.

Thanks for the reply!

Re: Overlaying Android Interface Objects

November 25, 2010 - 7:18am #8

I'm not sure if you can concatenate jstrings... I would just do this using C string functions, and then pass the finished string to the new jstring. You can use something like strcat (do a search online for how to use it), or my preference is sprintf. In either case you'll need to create a buffer large enough to hold the final string. Here's an example with sprintf:

char mystring[128];
sprintf(mystring, "trackable found: %s", trackable->getName());
jstring js = env->NewStringUTF(mystring);

- Kim

Re: Overlaying Android Interface Objects

November 25, 2010 - 3:53am #7

Thanks Kim for this code, it works well.

However I would like to use this code to display different messages. Is there a way to concatenate a jstring?

Re: Overlaying Android Interface Objects

November 8, 2010 - 8:40am #6

Yes, make sure that you are only calling this method when the visible target changes, not every frame that a target is visible. I believe the toasts get queued up and will no longer be responsive if you are continuously creating them.

That is the purpose of the lastTrackableId variable in the first code snippet, to only display a message on change :)

- Kim

Re: Overlaying Android Interface Objects

November 8, 2010 - 8:24am #5

Thanks Kim.

I fixed this a while ago now. Can't remember what was wrong, so I'm sorry if a solution ever needed.

What is happening though is the message doesn't really change when the trackable changes and upon exit of the application the Toast message remains.

Any hints as to why?

EDIT: I think I see what's happening.
There's a pop-up every frame and they can't keep up with the frame rate of the application and thus continue till they have completed all their requests even after the application has closed. Am I warm?

Re: Overlaying Android Interface Objects

November 8, 2010 - 5:23am #4

Can you try debugging your code to figure out which step is breaking? First, check to see if the displayMessage Java method is successfully called from native. In Eclipse, add a breakpoint to this method. Check the contents of the message, then step into the mainActivityHandler sendMessage call. If you're not familiar with the Eclipse debugger, you can also add println calls to both Java methods, and check logcat (open the DDMS perspective) to see that they are getting called.

- Kim

Re: Overlaying Android Interface Objects

November 8, 2010 - 3:42am #3

I gave this a shot and nothing happens when the teapots change...

Re: Overlaying Android Interface Objects

October 13, 2010 - 1:41pm #2

This is possible but somewhat tricky. If you're new to Android, you may want to start by creating the user interface without the Augmented Reality SDK, to learn how the Android UI works.

Then, I suggest copying the ImageTargets sample project as a starting point for an AR application. Add your custom user interface elements to it.

There are a few steps required for making changes to the Android UI when a trackable becomes active. Let's start with the native code. Here is a simple example for passing a message from native to Java when a trackable first comes into view. Add this to ImageTargets.cpp:

int lastTrackableId = -1;

JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv* env, jobject obj)
{
    ...
    
    // 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);
        
        // Compare this trackable's id to a globally stored id
        // If this is a new trackable, find the displayMessage java method and
        // call it with the trackable's name
        if (trackable->getId() != lastTrackableId) {
            jstring js = env->NewStringUTF(trackable->getName());
            jclass javaClass = env->GetObjectClass(obj);
            jmethodID method = env->GetMethodID(javaClass, "displayMessage", "(Ljava/lang/String;)V");
            env->CallVoidMethod(obj, method, js);
            lastTrackableId = trackable->getId();
        }
        
        ...
    }
    
    ...
}

Next, here's the java method that the native code is calling. Add this to the ImageTargetsRenderer class in 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 displayMessage(String text)
    {
        // We use a handler because this thread cannot change the UI
    	Message message = new Message();
    	message.obj = text;
        mainActivityHandler.sendMessage(message);
    }

Finally, you need to create and register this handler in the ImageTargets java class. The onResume method is a good place to do this:

    protected void onResume()
    {
        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;
            	int duration = Toast.LENGTH_SHORT;
            	Toast toast = Toast.makeText(context, text, duration);
            	toast.show();
            }
        };
    }

This example should display a temporary message on the screen when a new target comes into view (either the stones or chips targets that the ImageTargets sample uses). Hopefully this will get you started.

- Kim

Log in or register to post comments