<HTML>
<style> BODY { font-family:Arial, Helvetica, sans-serif;font-size:12px; }</style>


        
        
        
        <style type="text/css">p { margin-bottom: 0.08in; }a:link {  }</style><p class="western" style="margin-bottom: 0in;"><span style="font-style: normal; font-size: 12pt;">Hi,<br>
</span></p><p class="western" style="margin-bottom: 0in;"><br>
<span style="font-style: normal; font-size: 12pt;"></span></p><p class="western" style="margin-bottom: 0in;"><span style="font-style: normal; font-size: 12pt;">First of all. Thanks for the brilliant work!.... Running QT in Android is just mind-blowing!</span></p><p class="western" style="margin-bottom: 0in;"><span style="font-style: normal; font-size: 12pt;"><br>
</span></p><p class="western" style="margin-bottom: 0in;"><span style="font-style: normal; font-size: 12pt;">I just joined the list of developers to contribute to the project. Just after I got a copy of Necessitas 0.1 I had to see how to make the GPS work. I wanted to implement it as most as possible with JNI and with the minimum of java code.<br>
&nbsp;From a GPS example written in Java (<a href="http://hejp.co.uk/android/android-gps-example/)">http://hejp.co.uk/android/android-gps-example/)</a> I got that the main challenges were:<br>
1- To implement the LocationListener interface<br>
2- To connect to the location manager by Activity.getSystemService(service)<br>
3- To request the locations using the Listener by LocationManager.requestLocationUpdates(gps provider, double, float, listener,looper)<br>
<br>
This main challenges arose from two main constraints:<br>
1- The LocationListener is an interface so needs to be implemented in a class in a very basic way. Thus I had to include such implementation as part of the industrius java classes:&nbsp; QtGPSListener.java with the following implementation:<br>
<br>
package eu.licentia.necessitas.industrius;
<br>
&nbsp;import android.location.Location;
<br>
import android.location.LocationListener;
<br>
import android.location.LocationProvider;
<br>
import android.os.Bundle;
<br>
&nbsp;<br>
public class QtGPSListener implements LocationListener {
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void onLocationChanged(Location location)
<br>
&nbsp;&nbsp;&nbsp; {
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Here we get the location data and create a result
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // string (A really basic way of passing data). We called sndonLocationChanged that is
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // in fact connected to the qt application by JNI's registeNatives
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String accuracy;
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; accuracy = String.valueOf(location.getAccuracy());
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String altitude;
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; altitude = String.valueOf(location.getAltitude());
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String latitude;
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; latitude = String.valueOf(location.getLatitude());
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String longitude;
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; longitude = String.valueOf(location.getLongitude());
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String res;
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = "|AC:" + accuracy;
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = res + "|AL:" + altitude;
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = res + "|LA:" + latitude;
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = res + "|LO:" + longitude + "|";
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sndonLocationChanged(res);
<br>
&nbsp;&nbsp;&nbsp; }
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;<br>
&nbsp;&nbsp;&nbsp; public void onProviderDisabled(String provider)&nbsp;
<br>
&nbsp;&nbsp;&nbsp; {
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String res;
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res = "Provider " + provider + " is disabled";
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sndonProviderDisabled(res);
<br>
&nbsp;&nbsp;&nbsp; }
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;<br>
&nbsp;&nbsp;&nbsp; public void onProviderEnabled(String provider)&nbsp;
<br>
&nbsp;&nbsp;&nbsp; {
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String res;
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; res = "Provider " + provider + " is enabled";
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sndonProviderEnabled(res);
<br>
&nbsp;&nbsp;&nbsp; }
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;<br>
&nbsp;&nbsp;&nbsp; public void onStatusChanged(String provider, int status, Bundle extras)&nbsp;
<br>
&nbsp;&nbsp;&nbsp; {
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (status) {
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case LocationProvider.OUT_OF_SERVICE:
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sndonStatusChanged("Status Changed: Out of Service");
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case LocationProvider.TEMPORARILY_UNAVAILABLE:
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sndonStatusChanged("Status Changed: Temporarily Unavailable");
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case LocationProvider.AVAILABLE:
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sndonStatusChanged("Status Changed: Available");
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp; }
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // List of methods that will be linked in the qt application
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // using JNI's registerNatives
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static native void sndonLocationChanged(String currLocation);
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static native void sndonProviderDisabled(String message);
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static native void sndonProviderEnabled(String message);
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static native void sndonStatusChanged(String message);
<br>
&nbsp;&nbsp;&nbsp; &nbsp;<br>
}<br>
<br>
2- I had to use the activity running the qt application so I can use&nbsp; getSystemService(String). I though there were some Android API to get an instance to the current activity running (so I can use JNI to get it) but it seems that there is none.<br>
<br>
So the only alternative that I had was to pass the activity from QtApplication.java to qtmain_android.cpp. For this I made the following changes:<br>
&nbsp;&nbsp;&nbsp; <br>
2.1 -&nbsp; In QtApplication.java: FROM: public static native void startQtApp(String params,String env) TO: public static native void startQtApp(String params,String env,Object currAct)<br>
2.2 - In qtmain_android.cpp: FROM: static jboolean startQtApp(JNIEnv* env, jobject /*object*/, jstring paramsString, jstring environmentString) TO: tatic jboolean startQtApp(JNIEnv* env, jobject /*object*/, jstring paramsString, jstring environmentString,jobject currAct)<br>
2.3 -&nbsp; In qtmain_android.cpp: I created a jobject currActivity = NULL that I can extern in my sample application. Plus assigning it a global reference of the current activity:&nbsp; currActivity = env-&gt;NewGlobalRef(currAct). This to use it in JNI thread of execution <br>
<br>
With this changes I create a QT GPS class with JNI code that access the GPS. I just need to pass it the JavaVM that I extern from&nbsp; qtmain_android.cpp and&nbsp; currActivity.<br>
<br>
<br>
I can see that in 0.2 necessitas include QtLocation.java&nbsp; (which implements the GPS). Although it is fine, I reckon it is better to implement much of that code in the c++ side with JNI and only have the minimum java code just for implementing interfaces for example.<br>
<br>
This is an snapshot of the QT GPS class where it connects to the service<br>
<br>
<br>
midGetSystemService = currEnv-&gt;GetMethodID(actClass,"getSystemService","(Ljava/lang/String;)Ljava/lang/Object;");<br>
&nbsp;&nbsp;&nbsp; if (currEnv-&gt;ExceptionOccurred())<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //We need to handle errors a bit better! --TODO<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currEnv-&gt;ExceptionClear();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Cannot get method getSystemService()");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; if (midGetSystemService == NULL)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--getSystemService is null");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //We get a java String from a normal c++ string<br>
&nbsp;&nbsp;&nbsp; jstring StringArg = currEnv-&gt;NewStringUTF("location");<br>
&nbsp;&nbsp;&nbsp; if (currEnv-&gt;ExceptionOccurred())<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Error parsing string!");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //We get the system service<br>
&nbsp;&nbsp;&nbsp; jSystemServiceObj = currEnv-&gt;CallObjectMethod(currAct,midGetSystemService,StringArg);<br>
&nbsp;&nbsp;&nbsp; if (currEnv-&gt;ExceptionOccurred())<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Error at getting the System service");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //If the service object is not null we continue<br>
&nbsp;&nbsp;&nbsp; if (jSystemServiceObj == NULL)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--jSystemServiceObj is null");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //Now that we have the system service we need to create a new Location Listener object.<br>
<br>
&nbsp;&nbsp;&nbsp; // Gets the constructor of the Location Listener class. Please note that<br>
&nbsp;&nbsp;&nbsp; // listenerClass comes from the modified qtmain_android.cpp<br>
&nbsp;&nbsp;&nbsp; // It will not work with the orignal qtmain_android.cpp from android-lighthouse<br>
&nbsp; <br>
&nbsp;&nbsp; //In a better implementation like a mobility plugin we can get the class using Q_DECL_EXPORT JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* /*reserved*/)<br>
<br>
&nbsp;&nbsp;&nbsp; midConstListener = currEnv-&gt;GetMethodID(listenerClass, "&lt;init&gt;", "()V");<br>
&nbsp;&nbsp;&nbsp; if (currEnv-&gt;ExceptionOccurred())<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Error registering Listener constructor");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //If the method id of the constructor is not null we continue<br>
&nbsp;&nbsp;&nbsp; if (midConstListener == NULL)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--midConstListener is null");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //Creates a new listener class<br>
&nbsp;&nbsp;&nbsp; jListenerObj = currEnv-&gt;NewObject(listenerClass, midConstListener);<br>
&nbsp;&nbsp;&nbsp; if (currEnv-&gt;ExceptionOccurred())<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Error creating new listener object");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //If the listener class is not null we continue<br>
&nbsp;&nbsp;&nbsp; if (jListenerObj == NULL)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--jListenerObj is null");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //&nbsp; Now that we have the new instance of the listener object<br>
&nbsp;&nbsp;&nbsp; //&nbsp; We need to connect its callbacks to our methods<br>
<br>
&nbsp;&nbsp;&nbsp; //Declaring the methods. This will be used by registerNatives<br>
&nbsp;&nbsp;&nbsp; JNINativeMethod methods[] =<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"sndonLocationChanged", "(Ljava/lang/String;)V", (void *)&amp;androidGPS::LocationChanged},<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"sndonProviderDisabled", "(Ljava/lang/String;)V", (void *)&amp;androidGPS::ProviderDisabled},<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"sndonProviderEnabled", "(Ljava/lang/String;)V", (void *)&amp;androidGPS::ProviderEnabled},<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"sndonStatusChanged", "(Ljava/lang/String;)V", (void *)&amp;androidGPS::StatusChanged}<br>
&nbsp;&nbsp;&nbsp; };<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; //Register the native methods.<br>
&nbsp;&nbsp;&nbsp; // Basically this joins the methods inside the gpsListener.java class<br>
&nbsp;&nbsp;&nbsp; // with our c++ methods.<br>
&nbsp;&nbsp;&nbsp; int numMethods;<br>
&nbsp;&nbsp;&nbsp; numMethods = sizeof(methods) / sizeof(methods[0]);<br>
&nbsp;&nbsp;&nbsp; if (currEnv-&gt;RegisterNatives(listenerClass, methods, numMethods) &lt; 0)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (currEnv-&gt;ExceptionOccurred())<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Error running RegisterNatives");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Error running RegisterNatives");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; // Now that we have connected the methos is time to call<br>
&nbsp;&nbsp;&nbsp; // requestLocationUpdates using the jSystemServiceObj<br>
<br>
&nbsp;&nbsp;&nbsp; //Get the method id of requestLocationUpdates<br>
&nbsp;&nbsp;&nbsp; midRequestLocationUpdates = currEnv-&gt;GetMethodID(locManClass,"requestLocationUpdates","(Ljava/lang/String;JFLandroid/location/LocationListener;Landroid/os/Looper;)V");<br>
&nbsp;&nbsp;&nbsp; if (currEnv-&gt;ExceptionOccurred())<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //We need to handle errors a bit better! --TODO<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currEnv-&gt;ExceptionClear();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Cannot get method midRequestLocationUpdates()");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //If the method is not null we continue<br>
&nbsp;&nbsp;&nbsp; if (midRequestLocationUpdates == NULL)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--midRequestLocationUpdates is null");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; //Finally we call the Request updates<br>
&nbsp;&nbsp;&nbsp; qDebug() &lt;&lt; "Final call!!!";<br>
<br>
&nbsp;&nbsp;&nbsp; //Convert a c++ string into jstring<br>
&nbsp;&nbsp;&nbsp; StringArg = currEnv-&gt;NewStringUTF("gps");<br>
<br>
&nbsp;&nbsp;&nbsp; // Call RequestLocationUpdates of the System Service object<br>
&nbsp;&nbsp;&nbsp; // (jlong)20000 means that it will request location updated every 20 seconds<br>
&nbsp;&nbsp;&nbsp; // (jfloat)10 is the minimum distance interval for notifications, in meters<br>
&nbsp;&nbsp;&nbsp; // Note that we pass the listener object that we just created jListenerObj<br>
&nbsp;&nbsp;&nbsp; // and the looper that comes from the modified qtmain_android.cpp</span></p><p class="western" style="margin-bottom: 0in;"><span style="font-style: normal; font-size: 12pt;">&nbsp;&nbsp; // we can pass such values as user defined!!!!<br>
</span></p><p class="western" style="margin-bottom: 0in;"><span style="font-style: normal; font-size: 12pt;">&nbsp;&nbsp;&nbsp; currEnv-&gt;CallVoidMethod(jSystemServiceObj,midRequestLocationUpdates,StringArg,(jlong)20000,(jfloat)10,jListenerObj,currLoop);<br>
&nbsp;&nbsp;&nbsp; if (currEnv-&gt;ExceptionOccurred())<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classError = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emit error("JNI--Error calling midRequestLocationUpdates");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stopGPSService();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; //Return with error<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; //Ready... As it all bound the class the GPS server will update the location<br>
&nbsp;&nbsp;&nbsp; // every 20 seconds using the gpsListener. As the methods of the gpsListener<br>
&nbsp;&nbsp;&nbsp; // are bound to the c++ aplication by registerNatives we can have the readings. <br>
<br>
To conclude. A JNI implementation of the Android GPS service with very basic java code will require to have a Jobject pointing to the current activity running the QT application. This I reckon would make a Mobility plugin less dependent on external java coding. But where it would be the best place to implement this change? I made it on qtmain_android.cpp and qtApplication.java but for a&nbsp; Mobility plugin this might not be the case.<br>
<br>
I register myself on gitorious. For contributing do I need to work on a clone of master?<br>
</span></p><p class="western" style="margin-bottom: 0in;"><br>
<span style="font-style: normal; font-size: 12pt;"></span></p><p class="western" style="margin-bottom: 0in;"><span style="font-style: normal; font-size: 12pt;">Thanks a lot for the brilliant work!</span></p><p class="western" style="margin-bottom: 0in;"><span style="font-style: normal; font-size: 12pt;"><br>
</span></p>
 <BR></HTML>