I have the Galaxy tab GT-P1000 7 inch with firmware version 2.3.3 and Phones running Android 2.2. In both versions when ever I am trying to get the time from GPS, its showing 1 day advance from 1st jan 2012. Same code is working fine on Samsung, LG and Motorola Phones.
The Sample code for the App is,
package com.vxceed.dateTime;
import java.util.Calendar;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class SampleDateTimeActivity extends Activity {
private LocationManager locationManager;
private TextView tv;
String varTime="";
/**
* Location Listener
*/
LocationListener locationListener = new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
@Override
public void onProviderDisabled(String provider) {
Toast.makeText(SampleDateTimeActivity.this,"GPS off", Toast.LENGTH_SHORT).show();
}
@Override
public void onLocationChanged(Location location) {
setCurrentLocation(location);
}
};
private void setCurrentLocation(Location location) {
varTime=String.valueOf(location.getTime());
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
locationManager=(LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0, locationListener);
tv=(TextView)findViewById(R.id.textView1);
}
public void refreshTime(View v)
{
String currentGPSTime="";
currentGPSTime=varTime;
if(currentGPSTime.compareTo("")==0)
{
tv.setText("Time Not Available");
}
else
{
Calendar cal=Calendar.getInstance();
cal.setTimeInMillis(new Long(currentGPSTime));
long currentDeviceTime=Calendar.getInstance().getTimeInMillis();
Calendar cal2=Calendar.getInstance();
cal2.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE)-1,cal.get(Calendar.HOUR_OF_DAY),cal.get(Calendar.MINUTE));
long currentGPSTime_less_one_Day=cal2.getTimeInMillis();
tv.setText( "GPSTIME:"+cal.getTime().toString() +" \n GPS_TIME_in_Millis:"+varTime+"\nDevice_Time_in_millis:"+String.valueOf(currentDeviceTime) +"\nGPS Time -1 day:"+String.valueOf(currentGPSTime_less_one_Day));
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (locationManager != null && locationListener != null){
locationManager.removeUpdates(locationListener);
locationManager = null;
}
}
}
I have searched the Google and then referring the NMEA official document I figure out How to Use the NMEA data. Here is the Working Code for the NMEA listener:
NmeaListener nmeaListener = new NmeaListener() {
@Override
public void onNmeaReceived(long timestamp, String nmea) {
parse(nmea);
}
};
private boolean parse(String strNMEA) {
// Discard the sentence if its checksum does not match our calculated
// checksum
boolean bStatus = false;
try {
if (!IsValid(strNMEA)) {
return false;
}
String[] sArrNMEA = strNMEA.split(",");
String strNMEAType = sArrNMEA[0];
if (strNMEAType.equals("$GPRMC")) {
bStatus = ParseGPRMC(sArrNMEA);
} else {
bStatus = false;
}
sArrNMEA = null;
} catch (Exception e) {
}
return bStatus;
}
private boolean ParseGPRMC(String[] sArrNMEA) {
boolean result = false;
try {
if (sArrNMEA.length > 9) {
int Hr = 0;
int Mins = 0;
int Secs = 0;
if (!sArrNMEA[1].equals("")) {
Hr = Integer.parseInt(sArrNMEA[1].substring(0, 2));
Mins = Integer.parseInt(sArrNMEA[1].substring(2, 4));
if (sArrNMEA[1].length() > 6) {
Secs = Integer.parseInt(sArrNMEA[1].substring(4, 6));
} else {
Secs = Integer.parseInt(sArrNMEA[1].substring(4));
}
}
if (!sArrNMEA[9].equals("")) {
int Day = Integer.parseInt(sArrNMEA[9].substring(0, 2));
int Month = Integer.parseInt(sArrNMEA[9].substring(2, 4));
if (Month > 0) {
Month = Month - 1;
}
int Year = Integer.parseInt(sArrNMEA[9].substring(4));
Year = 2000 + Year;
if (!sArrNMEA[1].equals("")) {
Calendar cal = Calendar.getInstance(TimeZone
.getTimeZone("UTC"));
cal.set(Year, Month, Day, Hr, Mins, Secs);
nmeaTime = String.valueOf(cal.getTimeInMillis());
}
}
result = true;
}
} catch (Exception e) {
}
return result;
}
private boolean IsValid(String strNMEA) {
// Compare the characters after the asterisk to the calculation
strNMEA = strNMEA.replace("\r", "");
strNMEA = strNMEA.replace("\n", "");
return strNMEA.substring(0, strNMEA.length())
.substring(strNMEA.indexOf("*") + 1)
.equalsIgnoreCase(GetChecksum(strNMEA));
}
private String GetChecksum(String strNMEA) {
// Loop through all chars to get a checksum
int Checksum = 0;
try {
char ch = '\0';
for (int i = 0; i < strNMEA.length(); i++) {
ch = strNMEA.charAt(i);
if (ch == '$') {
// Ignore the dollar sign
} else if (ch == '*') {
// Stop processing before the asterisk
break;
} else {
// Is this the first value for the checksum?
if (Checksum == 0) {
// Yes. Set the checksum to the value
Checksum = (byte) ch;
} else {
// No. XOR the checksum with this character's value
Checksum = Checksum ^ (byte) ch;
}
}
}
} catch (Exception e) {
}
// Return the checksum formatted as a two-character hexadecimal
return Integer.toHexString(Checksum);
}