Introduction
This is a small tutorial about how I added location service to my Android device. In my case the android device is an ASUS eeepc 901 running Froyo from
http://www.android-x86.org/ project. The eeepc does not have a GPS chip on board, therefore the location data should be obtained from an external devcie, i.e. a bluetooth GPS adapter.
However, the main reason doing this is to gain better knowledge of the below Android framework concepts:
- location service
- bluetooth service
- remote service handling
- notification
- menu / preferences
- broadcast receiver
For whom only interested in this functionality, there is a nice application named
BlueGps4Droid, which I found out after I did this
exercise.
The approach is to receive the NMEA data using the available bluetooth port. After processing these data, the location data will be injected into the system using the so-called mock location provider. The advantage of this approach is that you can implement this using the standard
Android SDK.
The other way is to integrate the location function into the Android system. Then you will need the sources of your Android system. But you will get a more complete location service. In a next post I'll describe how I did that as well ...
What you need:
Overview
Basically this program is composed of following:
- Main activity to start/stop the sevices and to provide menu/preference to define the bluetooth device name
- Bluetotoh service
- Location service
Main activity
menu/preferences:
// init preferences
preferences = PreferenceManager.getDefaultSharedPreferences(this);
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch ( item.getItemId() ) {
case R.id.preferences:
Intent i = new Intent(this, Preferences.class);
startActivity(i);
break;
}
return true;
}
The menu structure is defined in menu/menu.xml and xml/preferences.xml.
You can do this in
Eclipse IDE as below.
Define menu:
Select your project,right click on it and select New -> Other -> Android -> "Android XML File"
Then press Add and select "Item"
Define preferences:
Like the menu creation, but select the "Preference"
Then add a "devicename" (EditTextPreference)
Bluetooth service
The used bluetooth API is from Android 2.0 and above.
When starting the bluetooth service, the device name is retrieved from the
shared preferences.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// SharedPreferences.Editor edit = sharedPreferences.edit();
mGpsDevice = sharedPreferences.getString(PREF_BLUETOOTH_DEVICE, "");
log("onStartCommand called, looking for device:" + mGpsDevice);
toast("Bluetooth service started");
me = new Thread(mTask);
me.start();
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
Refer to below codes:
_adapter = BluetoothAdapter.getDefaultAdapter();
_adapter.startDiscovery();
Scanning the bluetooth device is done in a new thread named mTask. After that the named device has been able to be found, another thread (named mProcTask) will be created to receive the GPS data and then to broadcast it
For sake of simplicity, not all of the NMEA data will be processed.
Location service
A mock location provider will be added here:
locMgr.addTestProvider(MOCK_PROVIDER,
/* req. netowork */ false,
/* req. Sat */ false,
/* req. Cell*/ false,
/* need money */ false,
/* has altitude */ true,
/* has speed */ true,
/* has bearing */ true,
/* power */ 0,
/* accuracy */ TEST_ACCURACY);
And the broad-casted data will be received and injected into the Android system:
class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String sentence = intent.getStringExtra(BluetoothUtil.NMEA_SENTENCE);
/* assumed data is a GPRMC sentence */
if ( sentence.startsWith("$GPRMC") ) {
procRMC(sentence);
} else if ( sentence.startsWith("$GPGGA") ) {
procGGA(sentence);
}
locMgr.setTestProviderLocation(MOCK_PROVIDER, mLoc);
}
Resources
You can download my codes from
here.
Also worth mentioning the
GPS status tool.