Skip to content

Commit f7f0ffa

Browse files
committedAug 15, 2011
added qtmain_android
1 parent 04f88ca commit f7f0ffa

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed
 

‎src/app/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
SET(QGIS_APP_SRCS
22
main.cpp
3+
qtmain_android.cpp
34
qgisapp.cpp
45
qgisappinterface.cpp
56
qgsabout.cpp
@@ -134,6 +135,13 @@ SET(QGIS_APP_SRCS
134135
gps/qgsgpsmarker.cpp
135136
)
136137

138+
IF (ANDROID)
139+
SET(QGIS_APP_SRCS
140+
${QGIS_APP_SRCS}
141+
qtmain_android.cpp
142+
)
143+
ENDIF (ANDROID)
144+
137145

138146
SET (QGIS_APP_MOC_HDRS
139147
qgisapp.h
@@ -358,6 +366,10 @@ INCLUDE_DIRECTORIES(
358366
gps
359367
)
360368

369+
IF (ANDROID)
370+
INCLUDE_DIRECTORIES(${ANDROID_NDK_TOOLCHAIN_ROOT}/sysroot/usr/include)
371+
ENDIF (ANDROID)
372+
361373
IF (HAVE_SPATIALITE)
362374
IF (WITH_INTERNAL_SPATIALITE)
363375
INCLUDE_DIRECTORIES(../core/spatialite/headers)

‎src/app/qtmain_android.cpp

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
Copyright (c) 2009-2011, BogDan Vatra <bog_dan_ro@yahoo.com>
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
* Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above copyright
10+
notice, this list of conditions and the following disclaimer in the
11+
documentation and/or other materials provided with the distribution.
12+
* Neither the name of the BogDan Vatra <bog_dan_ro@yahoo.com> nor the
13+
names of its contributors may be used to endorse or promote products
14+
derived from this software without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY BogDan Vatra <bog_dan_ro@yahoo.com> ''AS IS'' AND ANY
17+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
DISCLAIMED. IN NO EVENT SHALL BogDan Vatra <bog_dan_ro@yahoo.com> BE LIABLE FOR ANY
20+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
28+
#include <android/log.h>
29+
#include <pthread.h>
30+
#include <QSemaphore>
31+
#include <QDir>
32+
#include <QDebug>
33+
#include <qglobal.h>
34+
35+
#include <stdlib.h>
36+
37+
#include <jni.h>
38+
39+
static JavaVM *m_javaVM = NULL;
40+
static JNIEnv *m_env = NULL;
41+
static jobject objptr;
42+
static QSemaphore m_quitAppSemaphore;
43+
static QList<QByteArray> m_applicationParams;
44+
static const char * const QtApplicationClassPathName = "eu/licentia/necessitas/industrius/QtApplication";
45+
46+
extern "C" int main(int, char **); //use the standard main method to start the application
47+
static void * startMainMethod(void * /*data*/)
48+
{
49+
50+
char ** params;
51+
params=(char**)malloc(sizeof(char*)*m_applicationParams.length());
52+
for (int i=0;i<m_applicationParams.size();i++)
53+
params[i]= (char*)m_applicationParams[i].constData();
54+
55+
int ret = main(m_applicationParams.length(), params);
56+
57+
qDebug()<<"MainMethod finished, it's time to cleanup";
58+
free(params);
59+
Q_UNUSED(ret);
60+
61+
JNIEnv* env;
62+
if (m_javaVM->AttachCurrentThread(&env, NULL)<0)
63+
{
64+
qCritical()<<"AttachCurrentThread failed";
65+
return false;
66+
}
67+
jclass applicationClass = env->GetObjectClass(objptr);
68+
if (applicationClass){
69+
jmethodID quitApp = env->GetStaticMethodID(applicationClass, "quitApp", "()V");
70+
env->CallStaticVoidMethod(applicationClass, quitApp);
71+
}
72+
m_javaVM->DetachCurrentThread();
73+
return NULL;
74+
}
75+
76+
static jboolean startQtApp(JNIEnv* env, jobject /*object*/, jstring paramsString, jstring environmentString)
77+
{
78+
qDebug()<<"startQtApp";
79+
const char * nativeString = env->GetStringUTFChars(environmentString, 0);
80+
QByteArray string=nativeString;
81+
env->ReleaseStringUTFChars(environmentString, nativeString);
82+
m_applicationParams=string.split('\t');
83+
qDebug()<<"environmentString"<<string<<m_applicationParams;
84+
foreach (string, m_applicationParams)
85+
if (putenv(string.constData()))
86+
qWarning()<<"Can't set environment"<<string;
87+
88+
nativeString = env->GetStringUTFChars(paramsString, 0);
89+
string=nativeString;
90+
env->ReleaseStringUTFChars(paramsString, nativeString);
91+
92+
qDebug()<<"paramsString"<<string;
93+
m_applicationParams=string.split('\t');
94+
95+
// Go home
96+
QDir::setCurrent(QDir::homePath());
97+
98+
pthread_t appThread;
99+
return pthread_create(&appThread, NULL, startMainMethod, NULL)==0;
100+
}
101+
102+
103+
static JNINativeMethod methods[] = {
104+
{"startQtApp", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApp}
105+
};
106+
107+
/*
108+
* Register several native methods for one class.
109+
*/
110+
static int registerNativeMethods(JNIEnv* env, const char* className,
111+
JNINativeMethod* gMethods, int numMethods)
112+
{
113+
jclass clazz=env->FindClass(className);
114+
if (clazz == NULL)
115+
{
116+
__android_log_print(ANDROID_LOG_FATAL,"Qt", "Native registration unable to find class '%s'", className);
117+
return JNI_FALSE;
118+
}
119+
jmethodID constr = env->GetMethodID(clazz, "<init>", "()V");
120+
if(!constr) {
121+
__android_log_print(ANDROID_LOG_FATAL,"Qt", "Native registration unable to find constructor for class '%s'", className);
122+
return JNI_FALSE;;
123+
}
124+
jobject obj = env->NewObject(clazz, constr);
125+
objptr = env->NewGlobalRef(obj);
126+
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0)
127+
{
128+
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed for '%s'", className);
129+
return JNI_FALSE;
130+
}
131+
return JNI_TRUE;
132+
}
133+
134+
/*
135+
* Register native methods for all classes we know about.
136+
*/
137+
static int registerNatives(JNIEnv* env)
138+
{
139+
if (!registerNativeMethods(env, QtApplicationClassPathName, methods, sizeof(methods) / sizeof(methods[0])))
140+
return JNI_FALSE;
141+
142+
return JNI_TRUE;
143+
}
144+
145+
typedef union {
146+
JNIEnv* nativeEnvironment;
147+
void* venv;
148+
} UnionJNIEnvToVoid;
149+
150+
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
151+
{
152+
__android_log_print(ANDROID_LOG_INFO,"Qt", "qt start");
153+
UnionJNIEnvToVoid uenv;
154+
uenv.venv = NULL;
155+
m_javaVM = 0;
156+
157+
if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK)
158+
{
159+
__android_log_print(ANDROID_LOG_FATAL,"Qt","GetEnv failed");
160+
return -1;
161+
}
162+
m_env = uenv.nativeEnvironment;
163+
if (!registerNatives(m_env))
164+
{
165+
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
166+
return -1;
167+
}
168+
m_javaVM = vm;
169+
return JNI_VERSION_1_4;
170+
}

0 commit comments

Comments
 (0)
Please sign in to comment.