13

Tôi đang thực hiện một số thử nghiệm với hàm requestLocationUpdates() từ FusedLocationApi. Tôi đang sử dụng số PRIORITY_BALANCED_POWER_ACCURACY. Một chính xác khối thành phố là tốt cho tôi.Quyền ACCESS_COARSE_LOCATION cho độ chính xác tháp di động trên Android

Khi tôi yêu cầu sự cho phép ACCESS_FINE_LOCATION, tôi nhận được độ chính xác 100m tuyệt vời với mức giảm GPS. Vì tôi không cần độ chính xác GPS nhưng độ chính xác của khối thành phố, tôi chỉ muốn yêu cầu sự cho phép của ACCESS_COARSE_LOCATION. Tuy nhiên, khi tôi yêu cầu sự cho phép của ACCESS_COARSE_LOCATION, tôi nhận được độ chính xác 2 km. Có vẻ như thiết bị không còn sử dụng sự cho phép của Wifi và chỉ có độ chính xác của tháp di động.

Làm cách nào để có độ chính xác cao hơn với sự cho phép ACCESS_COARSE_LOCATION?

Lưu ý: GPS bị tắt trên thiết bị thử nghiệm của tôi.

+0

Google xây dựng mô hình vị trí bằng cách thu thập thông tin điểm truy cập từ những người dùng kết nối qua wifi và tháp di động. Càng có nhiều dữ liệu thu thập càng chính xác thì về mặt kỹ thuật, bạn cần nhiều người dùng Android hơn trong khu vực của mình. Mặt khác, có vẻ kỳ lạ là GPS có thể có độ chính xác theo thứ tự 100m hoặc 2km để truy cập thô. Bạn có chắc là bạn không tính toán sai? – inmyth

+0

Độ chính xác của GPS là về đồng hồ. Tôi đang làm tất cả các bài kiểm tra của tôi với GPS tắt. Thiết bị sử dụng wifi khi tôi đang sử dụng quyền ACCESS_FINE_LOCATION (Tôi có đủ người dùng Android trong khu vực của mình). Tôi sẽ nhận được kết quả chính xác tương tự khi sử dụng ACCESS_COARSE_LOCATION thay vì độ chính xác 2000m. – poiuytrez

Trả lời

37

Đây là một vấn đề thú vị, và tôi đã ấn tượng rằng việc sử dụng ACCESS_COARSE_LOCATION sẽ sử dụng WiFi, vì đó là những gì tài liệu nói.

Các tài liệu cho ACCESS_COARSE_LOCATION trạng thái:

Cho phép ứng dụng truy cập vị trí gần đúng nguồn gốc từ mạng nguồn vị trí như các tháp di động và Wi-Fi.

Vì vậy, tôi đặt nó vào thử nghiệm và kết quả thật đáng ngạc nhiên.

Đây là mã mà tôi sử dụng để thử nghiệm với:

public class MainActivity extends Activity implements 
     GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { 

    LocationRequest mLocationRequest; 
    GoogleApiClient mGoogleApiClient; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     buildGoogleApiClient(); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    protected void onPause(){ 
     super.onPause(); 
     if (mGoogleApiClient != null) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
     } 
    } 

    protected synchronized void buildGoogleApiClient() { 
     Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show(); 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show(); 

     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(10); 
     mLocationRequest.setFastestInterval(10); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
     //mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER); 
     //mLocationRequest.setSmallestDisplacement(0.1F); 

     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 

     Log.d("locationtesting", "accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude()); 

     Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show(); 
    } 
} 

AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 

build.gradle:

compile 'com.google.android.gms:play-services:7.3.0' 

Các thử nghiệm đầu tiên tôi làm là với PRIORITY_BALANCED_POWER_ACCURACY và không có WiFi. Lưu ý rằng tôi cũng bị vô hiệu hóa Always Allow Scanning, vì nó khẳng định:

Hãy Dịch vụ vị trí của Google và các ứng dụng khác quét Wi-Fi mạng, ngay cả khi Wi-Fi tắt

Vì vậy, mà có thể chắc chắn nghiêng các kết quả nếu nó được kích hoạt.

Lưu ý rằng tôi cũng đã đặt Chế độ vị trí ở Chế độ tiết kiệm pin cho tất cả các thử nghiệm, do đó, radio GPS đã tắt toàn bộ thời gian.

Dưới đây là kết quả của PRIORITY_BALANCED_POWER_ACCURACY, ACCESS_COARSE_LOCATION, và không có WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021 

Vì vậy, nó nói 2000 chính xác mét, và đây là cách xa các tọa độ thực tế là, mũi tên màu xanh lá cây cho thấy nơi tôi thực sự là:

enter image description here

Sau đó, tôi kích hoạt WiFi, và chạy thử nghiệm một lần nữa, và đáng ngạc nhiên, kết quả là giống hệt nhau!

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021 

Sau đó, tôi chuyển sang LocationRequest.PRIORITY_LOW_POWER trong LocationRequest trong khi vẫn giữ android.permission.ACCESS_COARSE_LOCATION trong AndroidManifest.xml.

Không WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021 

Với WiFi:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.40320943772021 

Kết quả thật giống hệt nhau một lần nữa! Sử dụng PRIORITY_LOW_POWER có cùng kết quả như sử dụng PRIORITY_BALANCED_POWER_ACCURACY, trong đó trạng thái WiFi dường như không ảnh hưởng đến độ chính xác của tọa độ.

Sau đó, chỉ cần để trang trải tất cả các căn cứ, tôi đã thay đổi trở lại LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, và chuyển các AndroidManifest.xml để ACCESS_FINE_LOCATION:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

Thử nghiệm đầu tiên, không có WiFi:

accuracy: 826.0 lat: 37.7825458 lon: -122.3948752 

Vì vậy, nó nói chính xác của 826 mét, và đây là cách nó gần như trên bản đồ:

enter image description here

Sau đó, tôi chạy trên WiFi, và đây là kết quả:

accuracy: 18.847 lat: 37.779679 lon: -122.3930918 

Nó nghĩa đen tại chỗ trên, như bạn có thể nhìn thấy trên bản đồ:

enter image description here

Dường như nó quan trọng ít hơn những gì bạn sử dụng trong mã số LocationRequest trong mã Java và nhiều quyền bạn sử dụng trong AndroidManifest.xml, vì kết quả ở đây cho thấy rõ ràng rằng khi sử dụng ACCESS_FINE_LOCATION, việc bật hoặc tắt radio WiFi đã tạo ra sự khác biệt lớn về độ chính xác, và nó cũng là acc urate nói chung. Nó chắc chắn có vẻ như là mặc dù tài liệu là một chút bỏ lỡ hàng đầu, và rằng trong khi sử dụng android.permission.ACCESS_COARSE_LOCATION, có WiFi radio hoặc tắt không tạo sự khác biệt khi ứng dụng của bạn là người duy nhất thực hiện yêu cầu vị trí.

Một điều khác mà trạng thái tài liệu là sử dụng PRIORITY_BALANCED_POWER_ACCURACY sẽ cho phép ứng dụng của bạn "phản hồi" trên các yêu cầu vị trí của các ứng dụng khác. Từ các tài liệu:

Họ sẽ chỉ được giao trách năng lượng cho khoảng thời gian được thiết lập bởi setInterval (dài), nhưng vẫn có thể nhận địa điểm kích hoạt bởi các ứng dụng khác với tốc độ lên đến setFastestInterval (dài) .

Vì vậy, nếu người dùng mở Google Maps, theo tài liệu, ứng dụng của bạn có thể có được vị trí chính xác hơn tại thời điểm đó. Đó là một trong những mặt tích cực của việc sử dụng Nhà cung cấp Vị trí Hợp nhất mới thay vì các API cũ hơn, vì nó làm giảm lượng pin cạn kiệt của ứng dụng mà không làm việc nhiều.

Chỉnh sửa: Tôi đã thực hiện kiểm tra chức năng này, để xem điều gì sẽ xảy ra khi sử dụng ACCESS_COARSE_LOCATION.

thử nghiệm đầu tiên: ACCESS_COARSE_LOCATION, PRIORITY_BALANCED_POWER_ACCURACY, và WiFi trên:

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662 

đó nếu đặt tôi ra trong nước, khá xa từ vị trí hiện tại của tôi. Sau đó, tôi đã thoát khỏi ứng dụng thử nghiệm, đã khởi chạy Google Maps, nơi tôi đặt chính xác vị trí của tôi, sau đó khởi chạy lại ứng dụng thử nghiệm. Ứng dụng thử nghiệm không thể quay trở lại vị trí từ Google Maps và kết quả chính xác giống như trước đây!

accuracy: 2000.0 lat: 37.78378378378378 lon: -122.38041129850662 

tôi lại thử nghiệm này một vài lần, chỉ để chắc chắn, nhưng nó thực sự trông giống như sử dụng ACCESS_COARSE_LOCATION cũng vô hiệu hóa khả năng của ứng dụng để "piggy-back" trên đến các địa điểm thu được bằng cách ứng dụng khác.

Dường như sử dụng ACCESS_COARSE_LOCATION trong AndroidManifest.xml thực sự làm tê liệt ứng dụng về việc nhận dữ liệu vị trí chính xác. Kết luận, điều duy nhất bạn thực sự có thể làm là kết hợp tốt nhất các cài đặt phù hợp với bạn và ứng dụng của bạn, và hy vọng kết quả của bài kiểm tra này có thể giúp bạn đưa ra quyết định đó.

+0

Thử nghiệm tuyệt vời. Tuy nhiên, tôi nghĩ rằng bạn đã sai về đoạn cuối của mình (trước khi kết thúc). Nếu người dùng mở Google Maps và các ứng dụng của chúng tôi yêu cầu ACCESS_COARSE_LOCATION, chúng tôi sẽ (không may) vẫn nhận được 2000m. Có vẻ như hệ thống muốn "giấu" một vị trí chính xác hơn 2000m. – poiuytrez

+0

@poiuytrez Điểm tốt, tôi đã giả định ở đó. Tôi đã nghĩ rằng các tọa độ sẽ chính xác hơn, bất kể độ chính xác được báo cáo. Tôi sẽ kiểm tra ngày hôm nay và cập nhật kết quả! –

+0

@poiuytrez Bạn đã đúng, kết quả kiểm tra cho thấy chức năng này không hoạt động với 'ACCESS_COARSE_LOCATION'. Tôi đã cập nhật câu trả lời với kết quả kiểm tra từ hôm nay. –

0

Khi bạn yêu cầu quyền ACCESS_COARSE_LOCATION, ứng dụng khách hợp nhất sẽ cung cấp cho bạn độ chính xác của khối thành phố, đó là hành vi dự định và được viết trong tài liệu. Có một cái nhìn here dưới "Chỉ định quyền ứng dụng"
Điều tôi có thể đề nghị là bạn sử dụng nhà cung cấp vị trí thông thường của android (không hợp nhất vị trí) và cố gắng truy cập vào nhà cung cấp NETWORK. Nó sẽ cung cấp cho bạn độ chính xác WIFI.

+0

Từ tài liệu: "Độ chính xác mức khối được xem là chính xác khoảng 100 mét. Sử dụng độ chính xác thô như vậy thường tiêu thụ ít năng lượng hơn". Nó phải là độ chính xác 100m, không chính xác đến 2000m. – poiuytrez

Các vấn đề liên quan