<html><body><div style="color:#000; background-color:#fff; font-family:times new roman, new york, times, serif;font-size:12pt"><div><span>Great !</span></div><div><span>Please let me know when you have something.</span></div><div><br><span></span></div><div><span>Cheers,</span></div><div><span>BogDan.<br></span></div><div><span></span></div><div><br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><div style="font-family: times new roman, new york, times, serif; font-size: 12pt;"><div style="font-family: times new roman, new york, times, serif; font-size: 12pt;"><font face="Arial" size="2"><hr size="1"><b><span style="font-weight:bold;">From:</span></b> Frameworks &lt;frameworks@qlands.com&gt;<br><b><span style="font-weight: bold;">To:</span></b> <br><b><span style="font-weight: bold;">Cc:</span></b> "necessitas-devel@kde.org" &lt;necessitas-devel@kde.org&gt;<br><b><span style="font-weight:
 bold;">Sent:</span></b> Thursday, June 2, 2011 8:10 PM<br><b><span style="font-weight: bold;">Subject:</span></b> Re: GPS service for android and suggested changes in Necessitas.<br></font><br>
Hi,<br><br>No problem.<br><br>I am working on the GPS mobility plug-in (giving that there is a way of <br>having the JObject of the current activity running the QT application).<br><br>Cheers,<br>Carlos.<br><br>On 06/01/2011 09:53 PM, BogDan wrote:<br>&gt; Hi,<br>&gt;<br>&gt;<br>&gt; Please accept my apologize for slow replay.<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt; ________________________________<br>&gt;&gt; From: "<a ymailto="mailto:frameworks@qlands.com" href="mailto:frameworks@qlands.com">frameworks@qlands.com</a>"&lt;<a ymailto="mailto:frameworks@qlands.com" href="mailto:frameworks@qlands.com">frameworks@qlands.com</a>&gt;<br>&gt;&gt; To: <a ymailto="mailto:necessitas-devel@kde.org" href="mailto:necessitas-devel@kde.org">necessitas-devel@kde.org</a><br>&gt;&gt; Sent: Sunday, May 29, 2011 10:58 AM<br>&gt;&gt; Subject: GPS service for android and suggested changes in Necessitas.<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;
 Hi,<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; First of all. Thanks for the brilliant work!.... Running QT in Android is just mind-blowing!<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; 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>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; Great, we have something in common :)<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt;&nbsp;  From a GPS example written in Java (http://hejp.co.uk/android/android-gps-example/) I got that the main challenges were:<br>&gt;&gt; 1- To implement the LocationListener interface<br>&gt;&gt; 2- To connect to the location manager by Activity.getSystemService(service)<br>&gt;&gt; 3- To request the locations using the Listener by LocationManager.requestLocationUpdates(gps provider, double, float,
 listener,looper)<br>&gt;&gt;<br>&gt;&gt; This main challenges arose from two main constraints:<br>&gt;&gt; 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>&gt;&gt;<br>&gt;&gt; package eu.licentia.necessitas.industrius;<br>&gt;&gt;&nbsp;  import android.location.Location;<br>&gt;&gt; import android.location.LocationListener;<br>&gt;&gt; import android.location.LocationProvider;<br>&gt;&gt; import android.os.Bundle;<br>&gt;&gt;&nbsp;  <br>&gt;&gt; public class QtGPSListener implements LocationListener {<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void onLocationChanged(Location location)<br>&gt;&gt;&nbsp; &nbsp; &nbsp; {<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Here we get the location data and
 create a result<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // string (A really basic way of passing data). We called sndonLocationChanged that is<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // in fact connected to the qt application by JNI's registeNatives<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String accuracy;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; accuracy = String.valueOf(location.getAccuracy());<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String altitude;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; altitude = String.valueOf(location.getAltitude());<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String latitude;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; latitude =
 String.valueOf(location.getLatitude());<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String longitude;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; longitude = String.valueOf(location.getLongitude());<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String res;<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = "|AC:" + accuracy;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = res + "|AL:" + altitude;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = res + "|LA:" + latitude;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = res + "|LO:" + longitude + "|";<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sndonLocationChanged(res);<br>&gt;&gt;&nbsp;
 &nbsp; &nbsp; }<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; public void onProviderDisabled(String provider) <br>&gt;&gt;&nbsp; &nbsp; &nbsp; {<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String res;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = "Provider " + provider + " is disabled";<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sndonProviderDisabled(res);<br>&gt;&gt;&nbsp; &nbsp; &nbsp; }<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; public void onProviderEnabled(String provider) <br>&gt;&gt;&nbsp; &nbsp; &nbsp; {<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String res;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = "Provider " + provider + " is enabled";<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sndonProviderEnabled(res);<br>&gt;&gt;&nbsp; &nbsp; &nbsp; }<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp;
 &nbsp; &nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; public void onStatusChanged(String provider, int status, Bundle extras) <br>&gt;&gt;&nbsp; &nbsp; &nbsp; {<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (status) {<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case LocationProvider.OUT_OF_SERVICE:<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sndonStatusChanged("Status Changed: Out of Service");<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case LocationProvider.TEMPORARILY_UNAVAILABLE:<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sndonStatusChanged("Status Changed: Temporarily Unavailable");<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
 case LocationProvider.AVAILABLE:<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sndonStatusChanged("Status Changed: Available");<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&gt;&gt;&nbsp;  <br>&gt;&gt;&nbsp; &nbsp; &nbsp; }<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // List of methods that will be linked in the qt application<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // using JNI's registerNatives<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public static native void sndonLocationChanged(String currLocation);<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public static native void sndonProviderDisabled(String message);<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public static native void sndonProviderEnabled(String message);<br>&gt;&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
 public static native void sndonStatusChanged(String message);<br>&gt;&gt;&nbsp; &nbsp; &nbsp;  <br>&gt;&gt; }<br>&gt;&gt;<br>&gt;&gt; 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>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; Actually it is, QtApplication.mainActivity()<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt; 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>&gt;&gt;&nbsp; &nbsp;  <br>&gt;&gt; 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>&gt;&gt; 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>&gt;&gt; 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>&gt;&gt;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; Hmm :)<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt; 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>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; 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>&gt;&gt;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; Agree with you !<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt; This is an snapshot of the QT GPS class where it connects to the service<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; [...]<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt; 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.<br>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; Please call QtApplication.mainActivity() to get it !<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt; This I reckon would make a Mobility plugin less dependent on external java coding.<br>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; It will be great, because the java part can't be updated, by Ministro
 service !<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt; 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>&gt;&gt;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; Please change current Mobility implementation ! You'll get Java_vm pointer when the plugin is loaded by application and QtApplication.mainActivity() is a static function which can be used to get current activity.<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt; I register myself on gitorious. For contributing do I need to work on a clone of master?<br>&gt;&gt;<br>&gt;&gt;&nbsp; &nbsp; &nbsp; <br>&gt; Please clone http://qt.gitorious.org/~taipan/qt-mobility/android-qt-mobility and use testing branch !<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br>&gt;&gt;<br>&gt;&gt; Thanks a lot for the brilliant work!<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt;&nbsp; &nbsp; &nbsp;
 <br>&gt; Thanks,<br>&gt;<br>&gt; I'm looking forward to hearing from you<br>&gt;<br>&gt; Cheers,<br>&gt; BogDan.<br>&gt;<br>&gt;<br>&gt; Again, sorry for slow replay.<br>&gt;<br>&gt;<br>&gt;&nbsp; &nbsp; <br><br>_______________________________________________<br>Necessitas-devel mailing list<br><a ymailto="mailto:Necessitas-devel@kde.org" href="mailto:Necessitas-devel@kde.org">Necessitas-devel@kde.org</a><br><a href="https://mail.kde.org/mailman/listinfo/necessitas-devel" target="_blank">https://mail.kde.org/mailman/listinfo/necessitas-devel</a><br><br><br></div></div></blockquote></div></div></body></html>