GPS service for android and suggested changes in Necessitas.

BogDan bog_dan_ro at yahoo.com
Wed Jun 1 20:53:53 CEST 2011


Hi,


Please accept my apologize for slow replay.

>________________________________
>From: "frameworks at qlands.com" <frameworks at qlands.com>
>To: necessitas-devel at kde.org
>Sent: Sunday, May 29, 2011 10:58 AM
>Subject: GPS service for android and suggested changes in Necessitas.
>
>
> 
>Hi,
>
>
>
>First of all. Thanks for the brilliant work!.... Running QT in Android is just mind-blowing!
>
>
>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.

Great, we have something in common :)


> From a GPS example written in Java (http://hejp.co.uk/android/android-gps-example/) I got that the main challenges were:
>1- To implement the LocationListener interface
>2- To connect to the location manager by Activity.getSystemService(service)
>3- To request the locations using the Listener by LocationManager.requestLocationUpdates(gps provider, double, float, listener,looper)
>
>This main challenges arose from two main constraints:
>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:  QtGPSListener.java with the following implementation:
>
>package eu.licentia.necessitas.industrius; 
> import android.location.Location; 
>import android.location.LocationListener; 
>import android.location.LocationProvider; 
>import android.os.Bundle; 
> 
>public class QtGPSListener implements LocationListener { 
> 
>        public void onLocationChanged(Location location) 
>    { 
>                // Here we get the location data and create a result 
>                // string (A really basic way of passing data). We called sndonLocationChanged that is 
>                // in fact connected to the qt application by JNI's registeNatives 
>                String accuracy; 
>                accuracy = String.valueOf(location.getAccuracy()); 
> 
>                String altitude; 
>                altitude = String.valueOf(location.getAltitude()); 
> 
>                String latitude; 
>                latitude = String.valueOf(location.getLatitude()); 
> 
>                String longitude; 
>                longitude = String.valueOf(location.getLongitude()); 
> 
>                String res; 
> 
>                res = "|AC:" + accuracy; 
>                res = res + "|AL:" + altitude; 
>                res = res + "|LA:" + latitude; 
>                res = res + "|LO:" + longitude + "|"; 
> 
>                sndonLocationChanged(res); 
>    } 
> 
>     
>    public void onProviderDisabled(String provider)  
>    { 
>                String res; 
>        res = "Provider " + provider + " is disabled"; 
>        sndonProviderDisabled(res); 
>    } 
> 
>     
>    public void onProviderEnabled(String provider)  
>    { 
>                String res; 
>        res = "Provider " + provider + " is enabled"; 
>        sndonProviderEnabled(res); 
>    } 
> 
>     
>    public void onStatusChanged(String provider, int status, Bundle extras)  
>    { 
>                switch (status) { 
>        case LocationProvider.OUT_OF_SERVICE: 
>            sndonStatusChanged("Status Changed: Out of Service"); 
>             
>            break; 
>        case LocationProvider.TEMPORARILY_UNAVAILABLE: 
>            sndonStatusChanged("Status Changed: Temporarily Unavailable"); 
>             
>            break; 
>        case LocationProvider.AVAILABLE: 
>            sndonStatusChanged("Status Changed: Available"); 
>             
>            break; 
>                } 
> 
>    } 
>        // List of methods that will be linked in the qt application 
>        // using JNI's registerNatives 
>        public static native void sndonLocationChanged(String currLocation); 
>        public static native void sndonProviderDisabled(String message); 
>        public static native void sndonProviderEnabled(String message); 
>        public static native void sndonStatusChanged(String message); 
>     
>}
>
>2- I had to use the activity running the qt application so I can use  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.

Actually it is, QtApplication.mainActivity()


>
>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:
>    
>2.1 -  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)
>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)
>2.3 -  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:  currActivity = env->NewGlobalRef(currAct). This to use it in JNI thread of execution 
>

Hmm :)


>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  qtmain_android.cpp and  currActivity.
>
>
>I can see that in 0.2 necessitas include QtLocation.java  (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.
>

Agree with you !


>
>This is an snapshot of the QT GPS class where it connects to the service
>
>
[...]

>
>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.

Please call QtApplication.mainActivity() to get it !


> This I reckon would make a Mobility plugin less dependent on external java coding.

It will be great, because the java part can't be updated, by Ministro service !


> 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  Mobility plugin this might not be the case.
>

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.  


>I register myself on gitorious. For contributing do I need to work on a clone of master?
>

Please clone http://qt.gitorious.org/~taipan/qt-mobility/android-qt-mobility and use testing branch !


>
>
>Thanks a lot for the brilliant work!
>
>
>

Thanks,

I'm looking forward to hearing from you

Cheers,
BogDan.


Again, sorry for slow replay.



More information about the Necessitas-devel mailing list