Opening browser from C++

2,004 views
Skip to first unread message

Muzza

unread,
Jun 20, 2011, 5:05:27 AM6/20/11
to android-ndk
Hi,

I need an event in my C++ code to start the web browser.
I have java function in my Activity class to do this:

private void OpenURL( String url )
{
Uri uriUrl = Uri.parse( url );
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
startActivity( intent );
}

And am calling it from C++ like this:

gJavaVM->AttachCurrentThread( &gAndroidActivityEnv, NULL );
jstring jstr = gAndroidActivityEnv->NewStringUTF("www.google.com");
jclass clazz = gAndroidActivityEnv->FindClass("com/
MyAndroidActivity");
jmethodID openURLFunction = gAndroidActivityEnv->GetMethodID(clazz,
"OpenURL", "(Ljava/lang/String;)V");
gAndroidActivityEnv->CallVoidMethod( gAndroidActivityThis,
openURLFunction, jstr );
gJavaVM->DetachCurrentThread();

The result is an immediate fault crash with just some system dump data
as output.
It gets in to OpenURL ok, and if I just replace it with some debug
output there is no problem. It's just the call to startActivity that
seems to be the problem.
OpenURL works fine when called from the Activity in Java.

I thought it was perhaps a thread issue, so I tried the
AttachCurrentThread, but clearly it doesn't do what I hoped it would.

Can anyone offer any suggestions please?
Thanks

Alexander Fradiani

unread,
Jun 21, 2011, 3:17:37 PM6/21/11
to andro...@googlegroups.com
Hi, i think you're calling an instance method, but the JNI call is not
using the Java object to be used when calling the function.

I open a browser from my c++ like this:

void jni_openURL(const char* url) {
//LLamar a funcion desde la instancia hungrypigs.
jclass appClass = mEnv->GetObjectClass(appClassObj);
jmethodID mid = mEnv->GetMethodID(appClass, "openURL",
"(Ljava/lang/String;)V");
mEnv->CallVoidMethod(appClassObj, mid, mEnv->NewStringUTF(url));
//llamar a la funcion
}

But you need to have appClassObj initiated, i do that calling a method
named nativeInstanceInit from Java:

void package_class_nativeInstanceInit(JNIEnv* env, jobject thiz) {
appClassObj = env->NewGlobalRef(thiz);
}

I used this guide:
http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/index.html

Hope that can help.

> --
> You received this message because you are subscribed to the Google Groups "android-ndk" group.
> To post to this group, send email to andro...@googlegroups.com.
> To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.
>
>

l.b.

unread,
Jun 21, 2011, 10:09:08 PM6/21/11
to andro...@googlegroups.com

 Hi. to start a browser, I think it's easier to use "am" comannd.

 char* args = {"/system/bin/am", "start","-a", "android.intent.action.VIEW", "http://www.google.com/"};
 if(fork() == 0) {
     execvp("/system/bin/am", args);
 }
 
 Sincerely,

Dianne Hackborn

unread,
Jun 23, 2011, 5:18:37 PM6/23/11
to andro...@googlegroups.com
No.  No no no no.  Do you see "am" documented anywhere in the SDK or NDK?  No.  This is not an API.

Use JNI.

And besides using JNI this is going to be like 100x faster to run.  Launching the am command requires starting a clean Dalvik instance in its own process (not forked from zygote) and it takes a *noticeable* amount of time for that to launch.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/android-ndk/-/6Mkd0NxveGEJ.

To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.



--
Dianne Hackborn
Android framework engineer
hac...@android.com

Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails.  All such questions should be posted on public forums, where I and others can see and answer them.

Alastair Murray

unread,
Jun 23, 2011, 9:25:25 PM6/23/11
to andro...@googlegroups.com
Thanks for the info, I'm still having problems though.
For some reason, using your code GetMethodID is returning NULL for me.
In my code GetMethodID was valid, but calling it resulted in a crash.

Could you give me some more details about the java side please?
Are you call a function in your Activity or somewhere else?

I'm copying the Activity env and class pointer, but then the call from c++ to java occurs
later, via a call to GLSurfaceView Render (this is the only 'link' in my game where java does a c++ call every frame)
I suspect that it's not working for me as I believe GLSurfaceView runs on a different thread.
I've tried adding the openURL function in to the surface view class too (and copying the env and pointer from there), but still no luck.

Thanks
Reply all
Reply to author
Forward
0 new messages