Tuesday 17 August 2010

Satellite Status on Android 1.5 and beyond

Long time no change, but recently I had some time to redo the YGPS app using the official APIs.

You might remember from the previous posts that I employed a trick to get to the satellite status. Since API 3 this trick is not required any more and indeed the security hole that allowed me to access this information has been plugged.

So now I am just using API 3, which is the base for the long out Cupcake Android release. The code will also work on subsequent Android releases, such as Eclair and Froyo.

Now, the API boasts a call to a GpsStatus object, which contains a list of the status of all visible satellites. It is accessed from the LocationManager and once you got it I can iterate over the satellites to get their status and draw them on a sky map, like so:


float scale = radius / 90.0f;
if (lp.isProviderEnabled(LocationManager.GPS_PROVIDER)){
gpsStatus = this.lp.getGpsStatus(gpsStatus);

float mX;
float mY;

for (GpsSatellite s: gpsStatus.getSatellites()){
float theta = - (s.getAzimuth() + 90);
float rad = (float) (theta * Math.PI/180.0f);
mX = (float)Math.cos(rad);
mY = -(float)Math.sin(rad);
float elevation = s.getElevation() - 90.0f;
if (elevation > 90 || s.getAzimuth() < 0 || s.getPrn() < 0){
continue;
}
float a = elevation * scale;

int x = (int)Math.round(centerX + (mX * a) - mBitmapAdjustment);
int y = (int)Math.round(centerY + (mY * a) - mBitmapAdjustment);
if (s.usedInFix()){
canvas.drawBitmap(mSatelliteBitmapUsed, x, y, gridPaint);
} else {
if (gpsStatus.getTimeToFirstFix() > 0){
canvas.drawBitmap(mSatelliteBitmapUnused, x, y, gridPaint);
} else {
canvas.drawBitmap(mSatelliteBitmapNoFix, x, y, gridPaint);
}
}
canvas.drawText(new Integer(s.getPrn()).toString(),x, y, textPaint);
}
}


As usual you can find the full code here.