Android:三星 Galaxy Tab 和 Android 2.2 设备显示 GPS 日期自 2012 年 1 月 1 日起提前 1 天

发布于 2024-12-24 16:11:43 字数 7148 浏览 5 评论 0原文

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


}

我搜索了Google,然后参考了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);
}

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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

比忠 2024-12-31 16:11:43

这似乎会影响所有三星库存固件,我正在向三星记录对此的担忧。它似乎与三星设备隔离。因此,如果您可以在其他设备上进行测试,或者安装自定义固件。两者都对我有用。你的代码看起来不错,没有任何问题,这是一个固件问题

编辑:我已经联系了韩国工程师 - 他们说他们不知道这个问题,但已经打了补丁,应该在 SGS 的最新更新中修复以及其他受影响的产品。 (当然,除非该设备有一段时间没有更新 - 所以不确定 SGT)他们说问题出在使用 Broadcomm 芯片的设备上......所以是的,

使用上面的代码。它似乎对我有用,必须在其他一些设备上检查它,但是是的

This seems to be affecting all stock Samsung firmwares, i am logging a concern with Samsung about this. It seems to be isolated to Samsung devices. So if you can test on another device, or install custom firmware. both of those have worked for me. and your code looks good, nothing wrong there, this is a firmware issue

EDIT: I have contacted the Korean Engineers - they have said they weren't aware of the problem but have patched and it should be fixed in the latest update for the SGS and other affected products. (unless of course that device hasn't had an update for a while - so not sure about the SGT) They have said the problem lies with the devices using Broadcomm chips...so yeah

Use the above code. it seems to work for me will have to check it on a few other devices but yeah

后eg是否自 2024-12-31 16:11:43

我怀疑三星希望这是一个闰年问题,该问题会在 2012 年 3 月 1 日之后消失。

很抱歉让您失望了 - 但事实并非如此!自 1 月 1 日以来,我们一直在三星手机上安装的 PhoneTrack 应用程序中发现此问题,并且至今仍然存在。

希望三星现在能够负责任地采取行动,为所有受此 GPS 驱动程序错误影响的设备发布更新。

I suspect that Samsung were hoping that it was a leap year issue which would just go away after March 1st, 2012.

Sorry to disappoint - but it hasn't! We have been seeing this problem with the app PhoneTrack installed on Samsung phones since January 1st and it is still there today.

Hopefully, Samsung will now act responsibly and issue updates for all devices affected by this GPS driver bug.

深海少女心 2024-12-31 16:11:43

我在运行 Android 4.0.3 的 Nexus S 上遇到了这个错误(令人恼火的是,导致一大堆数据的时间戳不正确)。

我昨天升级到 4.0.4,这似乎解决了这个问题。不确定是否有计划对以前的 Android 版本进行修复。

不过,这是一个真正的虫子咆哮......

I hit this bug on my Nexus S running Android 4.0.3 (annoyingly causing a whole bunch of data to be incorrectly timestamped).

I was upgraded to 4.0.4 yesterday and this seems to have fixed the issue. Not sure if there is a plan to issue fixes to previous Android versions.

A real howler of a bug though...

丑疤怪 2024-12-31 16:11:43

它对我有用,我用此函数替换了 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);

    }

It worked for me and I replaced IsValid(String strNMEA) method with this function:

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

    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文