Android 安卓:三星Galaxy标签和安卓2.2设备显示GPS日期从2012年1月1日起提前1天
我有Galaxy tab GT-P1000 7英寸,固件版本为2.3.3,手机运行Android 2.2。在这两个版本中,当我试图从GPS获取时间时,它显示从2012年1月1日起提前1天。同样的代码在三星、LG和摩托罗拉手机上运行良好 应用程序的示例代码是Android 安卓:三星Galaxy标签和安卓2.2设备显示GPS日期从2012年1月1日起提前1天,android,gps,galaxy-tab,nmea,Android,Gps,Galaxy Tab,Nmea,我有Galaxy tab GT-P1000 7英寸,固件版本为2.3.3,手机运行Android 2.2。在这两个版本中,当我试图从GPS获取时间时,它显示从2012年1月1日起提前1天。同样的代码在三星、LG和摩托罗拉手机上运行良好 应用程序的示例代码是 package com.vxceed.dateTime; import java.util.Calendar; import android.app.Activity; import android.content.Context; i
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;
}
}
}
我搜索了谷歌,然后参考了NMEA官方文件,我找到了如何使用NMEA数据的方法。以下是NMEA侦听器的工作代码:
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);
}
NmeaListener-NmeaListener=new-NmeaListener(){
@凌驾
已接收公共void onNmeaReceived(长时间戳,字符串nmea){
解析(nmea);
}
};
私有布尔解析(字符串strNMEA){
//如果句子的校验和与我们的计算结果不匹配,则丢弃该句子
//校验和
布尔b状态=假;
试一试{
如果(!IsValid(strNMEA)){
返回false;
}
字符串[]sArrNMEA=strNMEA.split(“,”);
字符串strNMEAType=sArrNMEA[0];
if(strNMEAType.equals($GPRMC))){
bStatus=ParseGPRMC(sArrNMEA);
}否则{
b状态=假;
}
sArrNMEA=null;
}捕获(例外e){
}
返回b状态;
}
私有布尔ParseGPRMC(字符串[]sArrNMEA){
布尔结果=假;
试一试{
如果(sArrNMEA.length>9){
int-Hr=0;
整数分钟=0;
整数秒=0;
如果(!sArrNMEA[1]。等于(“”){
Hr=Integer.parseInt(sArrNMEA[1]。子字符串(0,2));
Mins=Integer.parseInt(sArrNMEA[1]。子字符串(2,4));
if(sArrNMEA[1].length()>6){
Secs=Integer.parseInt(sArrNMEA[1]。子字符串(4,6));
}否则{
Secs=Integer.parseInt(sArrNMEA[1]。子字符串(4));
}
}
如果(!sArrNMEA[9]。等于(“”){
int Day=Integer.parseInt(sArrNMEA[9].子字符串(0,2));
int Month=Integer.parseInt(sArrNMEA[9].子字符串(2,4));
如果(月份>0){
月份=第1个月;
}
int Year=Integer.parseInt(sArrNMEA[9].子字符串(4));
年份=2000+年;
如果(!sArrNMEA[1]。等于(“”){
Calendar cal=Calendar.getInstance(时区
.getTimeZone(“UTC”);
校准设置(年、月、日、小时、分钟、秒);
nMatime=String.valueOf(cal.getTimeInMillis());
}
}
结果=真;
}
}捕获(例外e){
}
返回结果;
}
私有布尔值有效(字符串strNMEA){
//将星号后的字符与计算结果进行比较
strNMEA=strNMEA.replace(“\r”,”);
strNMEA=strNMEA.replace(“\n”,”);
返回strNMEA.substring(0,strNMEA.length())
.substring(strNMEA.indexOf(“*”)+1)
.equalsIgnoreCase(获取校验和(strNMEA));
}
私有字符串GetChecksum(字符串strNMEA){
//循环遍历所有字符以获得校验和
整数校验和=0;
试一试{
char ch='\0';
对于(int i=0;i
这似乎影响到了所有三星固件的库存,我正在记录三星对此的担忧。它似乎与三星设备隔离。因此,如果您可以在其他设备上进行测试,或安装自定义固件。这两个都对我有用。你的代码看起来不错,没有问题,这是固件问题
编辑:我已经联系了韩国工程师-他们说他们不知道这个问题,但已经修补,应该在SGS和其他受影响产品的最新更新中修复。(当然,除非那台设备已经有一段时间没有更新了——所以不能肯定SGT)他们说问题在于使用Broadcomm芯片的设备……所以是的
使用上述代码。这似乎对我有效,我必须在其他一些设备上检查它,但是的,我怀疑三星希望这是一个闰年问题,它将在2012年3月1日之后消失 对不起,让你失望了,但它没有!从1月1日起,我们就看到三星手机上安装的应用程序PhoneTrack存在这个问题,至今仍然存在
希望三星现在能采取负责任的行动,为所有受此GPS驱动程序错误影响的设备发布更新。我在运行安卓4.0.3的Nexus S上遇到了此错误(令人烦恼的是,导致大量数据的时间戳不正确) 我昨天升级到了4.0.4,这似乎解决了这个问题。不确定是否有计划对以前的Android版本进行修复
一个真正的错误呼啸者…它对我有效,我用这个函数替换了
IsValid(String strNMEA)
方法:
private boolean checksum(String strNMEA)
{
int checksum = 0;
strNMEA = strNMEA.replace("\r", "");
strNMEA = strNMEA.replace("\n", "");
String strChecksum = strNMEA.substring(strNMEA.indexOf("*") + 1);
String str = strNMEA.substring(1, strNMEA.indexOf("*"));
for (int i = 0; i < str.length(); i++) {
checksum = checksum ^ str.charAt(i);
}
return checksum == Integer.valueOf(strChecksum, 16);
}