Android 安卓:三星Galaxy标签和安卓2.2设备显示GPS日期从2012年1月1日起提前1天

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

我有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;
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);

    }