Android: вкладки Samsung Galaxy и устройства Android 2.2 с указанием даты GPS 1 день вперед с 1 января 2012 г. - PullRequest
25 голосов
/ 03 января 2012

У меня Galaxy Tab GT-P1000 7 дюймов с версией прошивки 2.3.3 и Телефоны под управлением Android 2.2.В обеих версиях, когда я пытаюсь получить время от GPS, он показывает 1-дневное повышение с 1 января 2012 года. Тот же код работает на телефонах Samsung, LG и Motorola.

Пример кода для приложения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;
        }
    }


}

Я искал в 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);
}

Ответы [ 4 ]

1 голос
/ 02 марта 2012

Я подозреваю, что Samsung надеялась, что это проблема високосного года, которая исчезнет после 1 марта 2012 года.

Извините, что разочаровала, но это не так!Мы наблюдаем эту проблему с приложением PhoneTrack, установленным на телефонах Samsung с 1 января, и оно все еще существует сегодня.

Надеемся, что Samsung теперь будет действовать ответственно и выпускать обновления для всех устройств, затронутых этой ошибкой драйвера GPS.

1 голос
/ 04 апреля 2012

Я столкнулся с этой ошибкой на моем Nexus S под управлением Android 4.0.3 (досадно, что целая куча данных была неправильно помечена меткой времени)

Вчера я был обновлен до 4.0.4, и это, похоже, решило проблему.Не уверен, что планируется выпустить исправления для предыдущих версий Android.

Реальный рев жука, хотя ...

1 голос
/ 05 января 2012

Это, похоже, влияет на все стоковые прошивки Samsung, я записываю озабоченность Samsung по этому поводу.Кажется, он изолирован от устройств Samsung.Так что, если вы можете проверить на другом устройстве, или установить пользовательскую прошивку.оба из них работали на меня.и ваш код выглядит хорошо, в этом нет ничего плохого, это проблема прошивки

РЕДАКТИРОВАТЬ: я связался с корейскими инженерами - они сказали, что они не знали о проблеме, но исправили, и это должно быть исправлено впоследнее обновление для SGS и других уязвимых продуктов.(если, конечно, это устройство некоторое время не обновлялось - поэтому не уверен насчет SGT) Они сказали, что проблема заключается в устройствах, использующих чипы Broadcomm ... так что да

Используйте приведенный выше код,мне кажется, что это сработает, придется проверить это на нескольких других устройствах, но да

0 голосов
/ 16 октября 2012

Это сработало для меня, и я заменил метод 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);

    }
...