Làm cách nào để kiểm tra trạng thái hiện tại của bộ thu GPS?


90

Làm cách nào để kiểm tra trạng thái hiện tại của bộ thu GPS? Tôi đã kiểm tra LocationListener onStatusChangedphương pháp nhưng bằng cách nào đó có vẻ như không hoạt động hoặc chỉ là khả năng sai.

Về cơ bản, tôi chỉ cần biết biểu tượng GPS ở đầu màn hình đang nhấp nháy (không có bản sửa lỗi thực tế) hay rắn (bản sửa lỗi có sẵn).

Câu trả lời:


150

Là một nhà phát triển của SpeedView: Đồng hồ tốc độ GPS cho Android, tôi hẳn đã thử mọi giải pháp khả thi cho vấn đề này, tất cả đều cho cùng một kết quả tiêu cực. Hãy nhắc lại những gì không hoạt động:

  1. onStatusChanged () không được gọi trên Eclair và Froyo.
  2. Tất nhiên, chỉ cần đếm tất cả các vệ tinh hiện có là vô ích.
  3. Kiểm tra xem có bất kỳ vệ tinh nào trả về true cho usedInFix () không cũng không hữu ích lắm. Hệ thống rõ ràng đã mất bản sửa lỗi nhưng vẫn tiếp tục báo cáo rằng vẫn còn một số sats được sử dụng trong đó.

Vì vậy, đây là giải pháp hiệu quả duy nhất tôi tìm thấy và giải pháp mà tôi thực sự sử dụng trong ứng dụng của mình. Giả sử chúng ta có lớp đơn giản này triển khai GpsStatus.Listener:

private class MyGPSListener implements GpsStatus.Listener {
    public void onGpsStatusChanged(int event) {
        switch (event) {
            case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                if (mLastLocation != null)
                    isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;

                if (isGPSFix) { // A fix has been acquired.
                    // Do something.
                } else { // The fix has been lost.
                    // Do something.
                }

                break;
            case GpsStatus.GPS_EVENT_FIRST_FIX:
                // Do something.
                isGPSFix = true;

                break;
        }
    }
}

OK, bây giờ trong onLocationChanged (), chúng tôi thêm những điều sau:

@Override
public void onLocationChanged(Location location) {
    if (location == null) return;

    mLastLocationMillis = SystemClock.elapsedRealtime();

    // Do something.

    mLastLocation = location;
}

Và đó là nó. Về cơ bản, đây là dòng thực hiện tất cả:

isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;

Tất nhiên, bạn có thể điều chỉnh giá trị mili, nhưng tôi khuyên bạn nên đặt nó khoảng 3-5 giây.

Điều này thực sự hoạt động và mặc dù tôi chưa xem mã nguồn vẽ biểu tượng GPS gốc, nhưng điều này gần với việc tái tạo hành vi của nó. Hy vọng điều này sẽ giúp ai đó.


Xin chào, tôi đang tự hỏi tại sao việc đếm các vệ tinh có sẵn là vô ích như trong ví dụ này? Nếu số lượng vệ tinh được tìm thấy là 0 có nghĩa là không có kết nối, hoặc tôi đã nhầm? groups.google.com/group/android-developers/browse_thread/thread/…
per_jansson

3
Xin chào Stephen, bạn có thể vui lòng giải thích tại sao isGPSFix hoạt động được không. Cảm ơn, Nick
nickfox

Nhân tiện, tôi nhận thấy rằng trong ICS, họ đã tăng thời gian cho đến khi hệ thống bắt đầu báo cáo rằng bản sửa lỗi GPS đã bị mất. Ít nhất trong 4.0.3, nó chính xác là 10 giây.
soundmaven

Hoạt động tốt và sử dụng 10 giây thay vì 3-5 cho ICS cũng hoạt động khá tốt. May mắn thay, sửa lỗi không phải là một tính năng cần thiết của ứng dụng của tôi nhưng thật tốt nếu có thể biết được nó. Cảm ơn.
Tom

1
Nhưng điều này không bị phá vỡ khi mLastLocationMillisđược thiết lập bởi một nguồn khác ngoài GPS? Hệ thống này sẽ hơn tuyên bố rằng isGPSFixlà đúng nhưng trong thực tế nó chỉ là bất kỳ sửa chữa (có thể một từ mạng điện thoại)
Patrick

25

Biểu tượng GPS dường như thay đổi trạng thái của nó theo ý định phát sóng đã nhận. Bạn có thể tự thay đổi trạng thái của nó bằng các mẫu mã sau:

Thông báo rằng GPS đã được bật:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

Thông báo rằng GPS đang nhận được các bản sửa lỗi:

Intent intent = new Intent("android.location.GPS_FIX_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

Thông báo rằng GPS không còn nhận được các bản sửa lỗi:

Intent intent = new Intent("android.location.GPS_FIX_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);

Thông báo rằng GPS đã bị tắt:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);

Mã ví dụ để đăng ký người nhận với ý định:

// MyReceiver must extend BroadcastReceiver
MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter("android.location.GPS_ENABLED_CHANGE");
filter.addAction("android.location.GPS_FIX_CHANGE");
registerReceiver(receiver, filter);

Bằng cách nhận các ý định phát sóng này, bạn có thể nhận thấy những thay đổi trong trạng thái GPS. Tuy nhiên, bạn sẽ chỉ được thông báo khi trạng thái thay đổi. Vì vậy, không thể xác định trạng thái hiện tại bằng cách sử dụng các ý định này.


Tôi không biết làm cách nào bạn có thể gửi chương trình phát sóng đó từ ứng dụng của mình vì có vẻ như đó là chương trình phát sóng được bảo vệ bởi hệ thống, nghĩa là chỉ hệ thống mới có thể gửi chương trình đó. Bất kỳ ứng dụng nào gửi ý định đó sẽ bị lỗi.
JoxTraex

Có thể gửi nó sáu năm trước, khi tôi viết câu trả lời. Rõ ràng họ đã thêm một số bảo vệ vào hệ thống kể từ đó.
sast

Tôi đang sử dụng những ý định này để biết khi nào các ứng dụng khác đang sử dụng GPS. Tôi tin rằng bắt đầu với Nougat, bạn thậm chí không thể lắng nghe những ý định này nữa, hoặc chúng đã thay đổi! Tôi không muốn nghe vị trí bằng ứng dụng của riêng mình. Bất cứ ai có ý tưởng nào khác?
Flyview

Có Tôi đã gặp sự cố đó: 05-14 10: 25: 24.113 17344-17344 / xxx.yyy.zzz.debug E / AndroidRuntime: FATAL EXCEPTION: main Process: xxx.yyy.zzz.debug, PID: 17344 java. lang.SecurityException: Quyền từ chối: không được phép gửi quảng bá android.location.GPS_FIX_CHANGE từ pid = 17344, uid = 10416
không giới

19

thành viên mới nên rất tiếc là tôi không thể bình luận hoặc bình chọn, tuy nhiên bài đăng của Stephen Daye ở trên là giải pháp hoàn hảo cho cùng một vấn đề mà tôi đang tìm kiếm trợ giúp.

một thay đổi nhỏ cho dòng sau:

isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;

đến:

isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < (GPS_UPDATE_INTERVAL * 2);

về cơ bản là tôi đang xây dựng một trò chơi có nhịp độ chậm và khoảng thời gian cập nhật của tôi đã được đặt thành 5 giây, khi tín hiệu gps bị tắt trong hơn 10 giây, đó là thời điểm thích hợp để kích hoạt một thứ gì đó.

chúc mừng bạn đời, đã dành khoảng 10 giờ để giải quyết giải pháp này trước khi tôi tìm thấy bài đăng của bạn :)


14

Được rồi, chúng ta hãy thử kết hợp tất cả các câu trả lời và cập nhật cho đến nay và làm điều gì đó như sau:

Trình nghe GPS có thể giống như sau:

GpsStatus.Listener listener = new GpsStatus.Listener() {
    void onGpsStatusChanged(int event) {
        if (event == GPS_EVENT_SATELLITE_STATUS) {
            GpsStatus status = mLocManager.getGpsStatus(null);
            Iterable<GpsSatellite> sats = status.getSatellites();
            // Check number of satellites in list to determine fix state
        }
    }
}

Các API hơi không rõ ràng về thời điểm và thông tin GPS và vệ tinh được cung cấp, nhưng tôi nghĩ một ý tưởng sẽ là xem xét có bao nhiêu vệ tinh. Nếu nó dưới ba, thì bạn không thể sửa chữa. Nếu nó nhiều hơn, thì bạn nên có một bản sửa lỗi.

Thử và sai có lẽ là cách để xác định tần suất Android báo cáo thông tin vệ tinh và mỗi GpsSatelliteđối tượng chứa thông tin gì .


vấn đề với việc đếm số vệ tinh có sẵn là ngay cả khi bạn có 5 vệ tinh đang xem, điều này không có nghĩa là luôn có thể sửa được. (Bạn có đề cập đến nó sửa bằng cách viết "Nếu đó là nhiều hơn, sau đó bạn nên có một sửa chữa")
NR1

Thật. Mặc dù tôi không biết thêm thông tin nào được yêu cầu để tạo thành một bản sửa lỗi, hoặc làm thế nào / liệu điều này có thể được truy xuất từ ​​một GpsSatelliteđối tượng hay không.
Christopher Orr

Một suy nghĩ khác .. bạn không đề cập đến điều này trong câu hỏi của mình, nhưng bạn đã thử chỉ sử dụng LocationManager.requestLocationUpdatesvới cài đặt thời gian và khoảng cách được đặt thành 0 chưa? Điều đó sẽ gửi cho bạn các bản sửa lỗi GPS ngay khi chúng xảy ra. Nếu bạn không nhận được bất kỳ thứ gì, thì rất có thể bạn không có cách sửa chữa. Bạn có thể kết hợp điều này với trình nghe trạng thái ở trên nếu bạn muốn.
Christopher Orr

1
Có thể lặp lại "sats" và kiểm tra usedInFix () trong GpsSatellite?
DeliriumTremens

8

Sau một vài năm làm việc với GPS trên Windows Mobile, tôi nhận ra rằng khái niệm "mất" bản sửa lỗi GPS có thể chủ quan. Để đơn giản lắng nghe những gì GPS nói với bạn, thêm một NMEAListener và phân tích cú pháp câu đó sẽ cho bạn biết liệu bản sửa lỗi có "hợp lệ" hay không. Xem http://www.gpsinformation.org/dale/nmea.htm#GGA . Thật không may với một số GPS, giá trị này sẽ dao động qua lại ngay cả trong quá trình hoạt động bình thường ở khu vực "sửa chữa tốt".

Vì vậy, giải pháp khác là so sánh thời gian UTC của vị trí GPS với thời gian của điện thoại (được chuyển đổi sang UTC). Nếu chúng cách nhau một khoảng thời gian nhất định, bạn có thể cho rằng mình đã mất vị trí GPS.


Bạn có muốn giải thích về phương pháp so sánh thời gian không? Trong câu trả lời của Stephen Daye, anh ấy đã so sánh sự khác biệt về thời gian giữa thời điểm lần sửa chữa cuối cùng xảy ra và sự kiện GPS_EVENT_SATELLITE_STATUS mới nhất ... Không chắc nó đang đo gì.
Rokey Ge

7

gặp sự cố tương tự khi làm việc trong dự án MSc của tôi, có vẻ như câu trả lời của Daye đã báo nhầm là "không có sửa chữa" trong khi thiết bị vẫn ở một vị trí tĩnh. Tôi đã sửa đổi giải pháp chỉ một chút mà dường như hoạt động tốt đối với tôi ở một vị trí tĩnh. Tôi không biết nó sẽ ảnh hưởng đến pin như thế nào vì nó không phải là mối quan tâm chính của tôi, nhưng đây là cách tôi đã thực hiện bằng cách yêu cầu lại cập nhật vị trí khi bản sửa lỗi đã hết thời gian.

private class MyGPSListener implements GpsStatus.Listener {
    public void onGpsStatusChanged(int event) {
        switch (event) {
        case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
            if (Global.getInstance().currentGPSLocation != null)
            {
                if((SystemClock.elapsedRealtime() - mLastLocationMillis) < 20000)
                {
                    if (!hasGPSFix) 
                        Log.i("GPS","Fix Acquired");
                    hasGPSFix = true;
                } 
                else
                {
                    if (hasGPSFix) 
                    {
                        Log.i("GPS","Fix Lost (expired)");
                        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
                    }
                    hasGPSFix = false;
                }
            }
            break;
        case GpsStatus.GPS_EVENT_FIRST_FIX:
            Log.i("GPS", "First Fix/ Refix");
            hasGPSFix = true;
            break;
        case GpsStatus.GPS_EVENT_STARTED:
            Log.i("GPS", "Started!");
            break;
        case GpsStatus.GPS_EVENT_STOPPED:
            Log.i("GPS", "Stopped");
            break;
        }
    }
}

5

Chà, kết hợp mọi phương pháp làm việc lại với nhau sẽ dẫn đến điều này (cũng giải quyết được vấn đề không dùng nữa GpsStatus.Listener):

private GnssStatus.Callback mGnssStatusCallback;
@Deprecated private GpsStatus.Listener mStatusListener;
private LocationManager mLocationManager;

@Override
public void onCreate() {
    mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

    mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    if (checkPermission()) {
       mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_UPDATE_INTERVAL, MIN_DISTANCE, this);
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        mGnssStatusCallback = new GnssStatus.Callback() {
            @Override
            public void onSatelliteStatusChanged(GnssStatus status) {
                satelliteStatusChanged();
            }

            @Override
            public void onFirstFix(int ttffMillis) {
                gpsFixAcquired();

            }
        };
        mLocationManager.registerGnssStatusCallback(mGnssStatusCallback);
    } else {
        mStatusListener = new GpsStatus.Listener() {
            @Override
            public void onGpsStatusChanged(int event) {
                switch (event) {
                    case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                        satelliteStatusChanged();
                        break;
                    case GpsStatus.GPS_EVENT_FIRST_FIX:
                        // Do something.
                        gpsFixAcquired();
                        break;
                }
            }
        };
        mLocationManager.addGpsStatusListener(mStatusListener);
    }
}

private void gpsFixAcquired() {
    // Do something.
    isGPSFix = true;
}

private void satelliteStatusChanged() {
    if (mLastLocation != null)
        isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < (GPS_UPDATE_INTERVAL * 2);

    if (isGPSFix) { // A fix has been acquired.
        // Do something.
    } else { // The fix has been lost.
        // Do something.
    }
}

@Override
public void onLocationChanged(Location location) {
    if (location == null) return;

    mLastLocationMillis = SystemClock.elapsedRealtime();

    mLastLocation = location;
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {

}

@Override
public void onProviderEnabled(String s) {

}

@Override
public void onProviderDisabled(String s) {

}

Lưu ý: câu trả lời này là sự kết hợp của các câu trả lời ở trên.


1
Miễn là bạn ghi nhận (các) tác giả khác, không có vấn đề gì với việc nhận được sự ủng hộ của riêng bạn cho tác phẩm mới hoặc tác phẩm phái sinh. Các quy tắc ở đây quan tâm nhiều hơn đến việc mọi người đạo văn câu trả lời của người khác và sử dụng chúng ở nơi khác trên Stack Overflow để thu hút người đại diện một cách không trung thực. Vì bạn đã đề cập rằng bạn đã xây dựng trên các câu trả lời khác, tôi nghĩ rằng điều này là tốt.
halfer

3

Nếu bạn chỉ cần biết liệu có cách khắc phục hay không, thì hãy kiểm tra vị trí đã biết gần đây nhất được cung cấp bởi bộ thu GPS và kiểm tra giá trị .getTime () để biết vị trí đó bao nhiêu tuổi. Nếu nó đủ gần đây (như ... một vài giây), bạn có một bản sửa lỗi.

   LocationManager lm = (LocationManager)context.getSystemService(LOCATION_SERVICE); 
   Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

   // Get the time of the last fix
   long lastFixTimeMillis = loc.getTime(); 

... và cuối cùng so sánh với thời gian hiện tại (Theo UTC!). Nếu nó đủ gần đây, bạn có một bản sửa lỗi.

Tôi làm điều đó trong ứng dụng của mình và cho đến nay rất tốt.


+1 có vẻ đáng để thử nếu bạn ngay lập tức muốn biết liệu có bản sửa lỗi hay không.
AgentKnopf


2

Tôi có thể sai nhưng có vẻ như mọi người dường như đang lạc đề về

tôi chỉ cần biết liệu biểu tượng gps ở đầu màn hình có nhấp nháy hay không (không có bản sửa lỗi thực tế)

Điều đó dễ dàng được thực hiện với

LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean gps_on = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);

Để xem liệu bạn có bản sửa lỗi vững chắc hay không, mọi thứ sẽ phức tạp hơn một chút:

public class whatever extends Activity {
    LocationManager lm;
    Location loc;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);        
        lm = (LocationManager) getSystemService(LOCATION_SERVICE);
        loc = null;
        request_updates();        
    }

    private void request_updates() {
        if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            // GPS is enabled on device so lets add a loopback for this locationmanager
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0, 0, locationListener);
        }      
    }

    LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            // Each time the location is changed we assign loc
            loc = location;
        }

         // Need these even if they do nothing. Can't remember why.
         public void onProviderDisabled(String arg0) {}
         public void onProviderEnabled(String provider) {}
         public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

Bây giờ bất cứ khi nào bạn muốn xem nếu bạn có sửa chữa?

if (loc != null){
    // Our location has changed at least once
    blah.....
}

Nếu bạn muốn trở nên lạ mắt, bạn luôn có thể có thời gian chờ bằng System.currentTimeMillis () và loc.getTime ()

Hoạt động đáng tin cậy, ít nhất là trên N1 kể từ 2.1.


3
Giải pháp của bạn là quá mức cho những gì nó làm. Tuy nhiên nó rất ít. Điều gì sẽ xảy ra nếu sau khi gps giải quyết vị trí của tôi, tôi đi đến ga tàu điện ngầm, do đó làm cho gps mất bản sửa lỗi?
marendre

1

Với LocationManager, bạn có thể getLastKnownLocation () sau khi bạn getBestProvider (). Điều này cung cấp cho bạn một đối tượng Vị trí, có các phương thức getAccuracy () tính bằng mét và getTime () tính bằng mili giây UTC

Điều này có cung cấp cho bạn đủ thông tin?

Hoặc có lẽ bạn có thể lặp lại LocationProviders và tìm hiểu xem mỗi người có đáp ứng Tiêu chí không (ACCURACY_COARSE)


1

rất nhiều bài viết ...

GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
                        public void onGpsStatusChanged(int event) {
                            if( event == GpsStatus.GPS_EVENT_FIRST_FIX){
                                showMessageDialog("GPS fixed");
                            }
                        }
                 };

thêm mã này, với addGpsListener ... showMessageDialog ... chỉ hiển thị một cửa sổ hộp thoại tiêu chuẩn với chuỗi

đã làm công việc hoàn hảo cho tôi :) cảm ơn rất nhiều: =) (sry cho bài đăng này, chưa thể bình chọn)


Đây chỉ là bản sửa lỗi đầu tiên. Điều gì sẽ xảy ra nếu bạn vào một đường hầm?
Leos Literak

1

Nếu bạn không cần cập nhật ngay khi bản sửa lỗi bị mất, bạn có thể sửa đổi giải pháp của Stephen Daye theo cách đó, bạn có một phương pháp kiểm tra xem bản sửa lỗi vẫn còn hay không.

Vì vậy, bạn có thể kiểm tra nó bất cứ khi nào bạn cần một số dữ liệu GPS và bạn không cần GpsStatus.Listener đó.

Các biến "toàn cục" là:

private Location lastKnownLocation;
private long lastKnownLocationTimeMillis = 0;
private boolean isGpsFix = false;

Đây là phương thức được gọi trong "onLocationChanged ()" để ghi nhớ thời gian cập nhật và vị trí hiện tại. Bên cạnh đó nó cập nhật "isGpsFix":

private void handlePositionResults(Location location) {
        if(location == null) return;

        lastKnownLocation = location;
        lastKnownLocationTimeMillis = SystemClock.elapsedRealtime();

        checkGpsFix(); // optional
    }

Phương pháp đó được gọi bất cứ khi nào tôi cần biết nếu có bản sửa lỗi GPS:

private boolean checkGpsFix(){

    if (SystemClock.elapsedRealtime() - lastKnownLocationTimeMillis < 3000) {
        isGpsFix = true;

    } else {
        isGpsFix = false;
        lastKnownLocation = null;
    }
    return isGpsFix;
}

Trong quá trình triển khai của mình, trước tiên, tôi chạy checkGpsFix () và nếu kết quả là đúng, tôi sử dụng biến "lastKnownLocation" làm vị trí hiện tại của mình.


1

Tôi biết điều này là hơi muộn. Tuy nhiên, tại sao không sử dụng NMEAListener nếu bạn muốn biết liệu bạn có cách khắc phục hay không. Từ những gì tôi đã đọc, NMEAListener sẽ cung cấp cho bạn các câu NMEA và từ đó bạn chọn câu đúng.

Câu RMC chứa trạng thái sửa chữa là A cho OK hoặc V cho cảnh báo. Câu GGA chứa Chất lượng sửa chữa (0 không hợp lệ, 1 GPS hoặc 2 DGPS)

Tôi không thể cung cấp cho bạn bất kỳ mã java nào vì tôi chỉ mới bắt đầu với Android, nhưng tôi đã tạo thư viện GPS trong C # cho các ứng dụng Windows, mà tôi đang tìm cách sử dụng với Xamarin. Tôi chỉ xem qua chủ đề này vì tôi đang tìm kiếm thông tin nhà cung cấp.

Từ những gì tôi đã đọc cho đến nay về đối tượng Location, tôi không cảm thấy thoải mái về các phương thức như getAccuracy () và hasAccuracy (). Tôi đã quen với việc trích xuất từ ​​các câu NMEA các giá trị HDOP và VDOP để xác định độ chính xác của các bản sửa lỗi của tôi. Việc có một bản sửa lỗi khá phổ biến, nhưng có HDOP tệ hại có nghĩa là độ chính xác theo chiều ngang của bạn không tốt lắm. Ví dụ, bạn đang ngồi tại bàn gỡ lỗi bằng thiết bị GPS Bluetooth bên ngoài áp sát vào cửa sổ, bạn có khả năng nhận được một bản sửa lỗi, nhưng HDOP và VDOP rất kém. Đặt thiết bị GPS của bạn trong một chậu hoa bên ngoài hoặc thứ gì đó tương tự hoặc thêm một thiết bị không khí bên ngoài vào GPS và ngay lập tức bạn nhận được các giá trị HDOP và VDOP tốt.


0

Có thể đó là khả năng tốt nhất để tạo TimerTask đặt Vị trí nhận được thành một giá trị nhất định (null?) Thường xuyên. Nếu GPSListener nhận được giá trị mới, nó sẽ cập nhật vị trí với dữ liệu hiện tại.

Tôi nghĩ rằng đó sẽ là một giải pháp hiệu quả.


0

Bạn nói rằng bạn đã thử onStatusChanged (), nhưng điều đó không hiệu quả với tôi.

Đây là phương pháp tôi sử dụng (tôi để lớp tự xử lý onStatusChanged):

private void startLocationTracking() {
    final int updateTime = 2000; // ms
    final int updateDistance = 10; // meter
    final Criteria criteria = new Criteria();
    criteria.setCostAllowed(false);
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    final String p = locationManager.getBestProvider(criteria, true);
    locationManager.requestLocationUpdates(p, updateTime, updateDistance,
            this);
}

Và tôi xử lý onStatusChanged như sau:

void onStatusChanged(final String provider, final int status,
        final Bundle extras) {
    switch (status) {
    case LocationProvider.OUT_OF_SERVICE:
        if (location == null || location.getProvider().equals(provider)) {
            statusString = "No Service";
            location = null;
        }
        break;
    case LocationProvider.TEMPORARILY_UNAVAILABLE:
        if (location == null || location.getProvider().equals(provider)) {
            statusString = "no fix";
        }
        break;
    case LocationProvider.AVAILABLE:
        statusString = "fix";
        break;
    }
}

Lưu ý rằng các phương thức onProvider {Dis, En} abled () là về việc bật và tắt tính năng theo dõi GPS của người dùng; không phải những gì bạn đang tìm kiếm.


Thật không may, nó thường không hoạt động. onLocationChanged () được gọi mỗi giây một lần, nhưng onStatusChanged hoàn toàn không được gọi. Đôi khi tôi ước mình có thể truy vấn trạng thái hiện tại thay vì chờ đợi một thông báo có thể không đến trong một thời gian dài hoặc bao giờ.
Edward Falk

2
Đúng. Tôi đã tự học được một vài điều sau câu trả lời trước đó và một là không phải tất cả các nền tảng Android đều giống nhau. Tôi chắc chắn thấy các cuộc gọi đến onStatusChanged trên cả HTC Hero và Archos 5 của tôi, nhưng tôi không ngạc nhiên khi nó không hoạt động ở mọi nơi. Còn kế hoạch B thì sao: bạn sử dụng GPSStatusListener được hiển thị trong một câu trả lời khác và chỉ cần xem có bất kỳ vệ tinh nào trả về true cho usedInFix () hay không. Theo kinh nghiệm của tôi, điều đó gần nhất với hoạt động của biểu tượng GPS tiêu chuẩn. (Các bạn đã cố gắng để tìm ra nguồn mà cụ mà biểu tượng tiêu chuẩn, BTW?)
CvR

0

Đặt khoảng thời gian để kiểm tra sửa lỗi không phải là một lựa chọn tốt .. tôi nhận thấy rằng onLocationChanged không được gọi nếu bạn không di chuyển .. điều có thể hiểu được vì vị trí không thay đổi :)

Cách tốt hơn sẽ là ví dụ:

  • kiểm tra khoảng thời gian đến vị trí cuối cùng nhận được (trong gpsStatusChanged)
  • nếu khoảng thời gian đó nhiều hơn 15 giây, hãy đặt biến: long_interval = true
  • xóa trình nghe vị trí và thêm lại, thường thì bạn sẽ nhận được vị trí cập nhật nếu vị trí thực sự có sẵn, nếu không - bạn có thể bị mất vị trí
  • trong onLocationChanged, bạn vừa đặt long_interval thành false ..
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.