Android SDK comes with one built-in location provider called "gps". This location provider moves along a predetermined route - obviously around Google premises. I was curious whether it is possible to introduce one's own location provider into the system therefore I took apart android.server.LocationProviderService. I found that it is relatively easy to introduce one's own location track which is then presented as new location provider to Android applications. Creating a new location provider software module turned out to be more complicated and eventually I did not try that out. LocationProviderService is able to handle location providers with their own Java logic but unfortunately the classes of these providers are loaded by the own classloader of LocationProviderService. This means that it is not possible to deploy the location provider software module as a package (apk), one has to fiddle with the software base of the Android system.
I did not do it because, to my pleasant surprise, Android's own location provider turned to be a pretty versatile simulator itself. Deploying own location providers based on track data really works like a charm. The LocationProviderService loads providers from under the /data/misc/location directory (device-based path). Each subdirectory under this directory is a location provider and the name of the location provider equals to the name of the subdirectory. The files in the subdirectory define the provider. As an example, you can go to the tools subdirectory of the example program package and run pull_gps.bat (emulator needs to be running when you do this). This batch file will fetch the three files associated with the "gps" provider as gps_location, gps_nmea and gps_properties (their original names on the device are location, nmea and properties, respectively, under the subdirectory called gps). The properties file describes the properties of the location provider in an easy to understand textual format. The location file is the last known location and the nmea is the track info in NMEA format. Well, I am not familiar with location format and I don't know what NMEA format is. There are two other possibilities: instead of "nmea" file, you can have "kml" or "track". In case of "kml", the track data is in KML format while "track" is a very simple textual format. I went for the latter and didn't try the former one - erm, I left that execise to the interested reader. ;-)
You can download the example program from here.
The "track" format is simple. It looks like this:
time longitude latitude altitude [bearing speed]
We have another provider called "triglav" beside the original "gps" provider. Select that provider and launch the "Display location" menu item. You will see us climbing the Triglav peak in 8 minutes (the altitude rises steadily to almost 3000 meters). When we reach the peak, we go back on our track to the origin and so on, this is the property of LocationProviderService.
Don't forget to look around on the peak, the panorama is said to be magnificient.
5 comments:
I followed your steps. But I am unable to find triglav in my lovationproviderList.
Here is my console
D:\Android\android-sdk_m5-rc15_windows\tools>java ozitotrack -s20 triglavMT.plt triglav
Track length: 8.776666666666667 minutes (0.14627777777777778 hours approx.)
D:\Android\android-sdk_m5-rc15_windows\tools>pull_gps.bat triglav
D:\Android\android-sdk_m5-rc15_windows\tools>rem last known location
D:\Android\android-sdk_m5-rc15_windows\tools>rem String providerName = tokens[idx++];
D:\Android\android-sdk_m5-rc15_windows\tools>rem long time = Long.parseLong(tokens[idx++]);
D:\Android\android-sdk_m5-rc15_windows\tools>rem double latitude = Double.parseDouble(tokens[idx++]);
D:\Android\android-sdk_m5-rc15_windows\tools>rem double longitude = Double.parseDouble(tokens[idx++]);
D:\Android\android-sdk_m5-rc15_windows\tools>rem double altitude = Double.parseDouble(tokens[idx++]);
D:\Android\android-sdk_m5-rc15_windows\tools>rem float bearing = Float.parseFloat(tokens[idx++]);
D:\Android\android-sdk_m5-rc15_windows\tools>rem float speed = Float.parseFloat(tokens[idx++]);
D:\Android\android-sdk_m5-rc15_windows\tools>adb pull /data/misc/location/gps/location gps_location
2 KB/s (0 bytes in 77.000s)
D:\Android\android-sdk_m5-rc15_windows\tools>adb pull /data/misc/location/gps/nmea gps_nmea
180 KB/s (0 bytes in 11568.000s)
D:\Android\android-sdk_m5-rc15_windows\tools>rem (time> (long> (lat> (alt> [(bearing> (speed>]
D:\Android\android-sdk_m5-rc15_windows\tools>rem adb pull /data/misc/location/gps/track gps_track
D:\Android\android-sdk_m5-rc15_windows\tools>adb pull /data/misc/location/gps/properties gps_properties
12 KB/s (0 bytes in 193.000s)
Here's my own GPS android tutorial.
http://www.androidph.com/2009/02/app-10-beer-radar.html
Hi Gabor,
Does this mean I can add my own "coordinates" in which android will try and locate me?
As an example, Google Maps doesn't work quite well in my city. Following ur tutorial do you think I could add some locations from the city and have it working on an application?
Btw, have you tried skying in Pohorje? I heard its not the same as Triglav, but it's also a nice ride :)
bern, you misunderstand the example.
This example (which worked before the 1.0, I understand, nowadays there are problems with the test "gps" provider in the SDK) simulated the movement of the device in case of the SDK when no real movement takes place. I fed this Triglav hike into the test provider and presto, it worked. The purpose of this sample is to replace the GPS receiver for testing. It does not help you in real-life situation.
I need to add the own provider by using code instead of pushing location files.Can someone help me to do this?
Post a Comment