2015-10-29 12 views
9

Ứng dụng của tôi đang cố gắng truy cập vào vị trí của thiết bị và tôi đã bao gồm những điều sau đây trong AndroidManifest.xml:ACCESS_FINE_LOCATION SecurityException bất chấp quy định cụ thể cho phép trong file manifest

<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.app"> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

    <application> 
     <meta-data android:name="com.google.android.gms.version" /> 
    </application> 

</manifest> 

tôi đã triển khai GoogleApiClient.ConnectionCallbacks như sau để truy cập vào vị trí dịch vụ:

public class BackgroundLocationService implements 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener { 

    private static final String TAG = BackgroundLocationService.class.getSimpleName(); 

    private static GoogleApiClient googleApiClient; 
    private static PendingIntent locationCallback; 

    public static int LOCATION_INTERVAL = 10000; 
    public static int FAST_INTERVAL = 5000; 

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.i(TAG, "Connected to Google API"); 

     LocationRequest request = new LocationRequest(); 
     request.setInterval(LOCATION_INTERVAL); 
     request.setFastestInterval(FAST_INTERVAL); 
     request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 

     LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, locationCallback); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.i(TAG, Integer.toString(i)); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.i(TAG, connectionResult.toString()); 
    } 
} 

Khi tôi kích hoạt các cuộc gọi dịch vụ vị trí, các ngoại lệ sau đây được ném:

java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations. 
    at android.os.Parcel.readException(Parcel.java:1599) 
    at android.os.Parcel.readException(Parcel.java:1552) 
    at com.google.android.gms.location.internal.zzi$zza$zza.zza(Unknown Source) 
    at com.google.android.gms.location.internal.zzk.zza(Unknown Source) 
    at com.google.android.gms.location.internal.zzl.zza(Unknown Source) 
    at com.google.android.gms.location.internal.zzd$7.zza(Unknown Source) 
    at com.google.android.gms.location.internal.zzd$7.zza(Unknown Source) 
    at com.google.android.gms.internal.zzlb$zza.zzb(Unknown Source) 
    at com.google.android.gms.internal.zzlf.zza(Unknown Source) 
    at com.google.android.gms.internal.zzlf.zzb(Unknown Source) 
    at com.google.android.gms.internal.zzli.zzb(Unknown Source) 
    at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source) 
    at com.localz.spotzpush.sdk.service.BackgroundLocationService.onConnected(BackgroundLocationService.java:45) 
    at com.google.android.gms.common.internal.zzk.zzh(Unknown Source) 
    at com.google.android.gms.internal.zzlg.zznU(Unknown Source) 
    at com.google.android.gms.internal.zzlg.onConnected(Unknown Source) 
    at com.google.android.gms.internal.zzli$2.onConnected(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zzg.zzpf(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zza.zzc(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zza.zzt(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zzc.zzph(Unknown Source) 
    at com.google.android.gms.common.internal.zzj$zzb.handleMessage(Unknown Source) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Tôi đang sử dụng thiết bị thực tế để tạo ra sự cố này và đã gãi đầu về lý do ngoại lệ bị ném.

+0

'minSdkVersion' và' targetSdkVersion' của bạn là gì? – JBirdVegas

+0

Hey @JBirdVegas, chúng tương ứng là 15 và 23 – gyamana

Trả lời

14

vấn đề này được gây ra bởi một tính năng mới dành cho Android 6.0.

Bắt đầu từ Android 6.0 (API cấp 23), người dùng cấp quyền cho ứng dụng trong khi ứng dụng đang chạy, không phải khi họ cài đặt ứng dụng.

http://developer.android.com/training/permissions/requesting.html

Để khắc phục vấn đề này khi được sự cho phép không được cấp một cách rõ ràng, tôi đã đưa vào một tấm séc để bọc các cuộc gọi dịch vụ vị trí (theo tài liệu của Google, một chút thay đổi).

int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION); 

if (permissionCheck == PackageManager.PERMISSION_GRANTED) { 
    //Execute location service call if user has explicitly granted ACCESS_FINE_LOCATION.. 
} 

Tài liệu của Google cũng hướng dẫn cách yêu cầu các quyền cần thiết.

CẬP NHẬT thứ 12 Oct 2016

Thêm trong bản cập nhật @Siddharth 's để bao gồm một câu trả lời hữu ích hơn cho checkSelfPermission()

//For this example, run the check onResume() 
@Override 
public void onResume() { 

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED) { 

     // Should we show an explanation? 
     if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { 

      // Show an expanation to the user *asynchronously* -- don't block 
      // this thread waiting for the user's response! After the user 
      // sees the explanation, try again to request the permission. 

     } else { 

      // No explanation needed, we can request the permission. 
      // PERMISSION_REQUEST_ACCESS_FINE_LOCATION can be any unique int 
      ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_ACCESS_FINE_LOCATION); 
     } 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, 
             String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case PERMISSION_REQUEST_ACCESS_FINE_LOCATION: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 
        && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

       // permission was granted, yay! Do the 
       // contacts-related task you need to do. 

      } else { 

       // permission denied, boo! Disable the 
       // functionality that depends on this permission. 
      } 
      return; 
     } 

     // other 'case' lines to check for other 
     // permissions this app might request 
    } 
} 
+1

Tôi nhận được java.lang.SecurityException: Khách hàng phải có quyền ACCESS_FINE_LOCATION để yêu cầu các vị trí PRIORITY_HIGH_ACCURACY. sự cố với Target SDK 22 trên Android 5.1 (Thiết bị là S cộng (GiONEE_WBL7511)) Bất kỳ manh mối nào? – arpitgoyal2008

+0

Vui lòng xem lại câu trả lời của tôi và thực hiện các chỉnh sửa thích hợp. Tôi sẽ xóa câu trả lời của tôi nếu bạn có thể sửa chữa câu trả lời của mình. – Siddharth

+0

@Siddharth, OK, cảm ơn vì điều đó, sẽ cập nhật câu trả lời của tôi ngay bây giờ – gyamana

0

Cấu trúc mặc định của LocationSource không nhất thiết phải sử dụng GPS để trả lại các vị trí chính xác.

Nếu tôi loại bỏ các phép "ACCESS_FINE_LOCATION" trong file Manifest, ngay sau khi tôi cố gắng để hiển thị bản đồ, các ứng dụng bị treo

Điều này là do việc thực hiện mặc định sử dụng LocationClient với LocationRequest.PRIORITY_HIGH_ACCURACY.

GoogleMap.setMyLocationEnabled khi bạn chỉ yêu cầu quyền ACCESS_COARSE_LOCATION, nhưng chuyển sang LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY.

Xem Android: Google Maps location with low battery usage

0

Đối với tất cả mọi người khác có lỗi với câu trả lời gyamana tại Manifest.permission. Lỗi ACCESS_FINE_LOCATION. Đảm bảo bạn đang sử dụng android.Manifest thay vì my.app.package.Manifest.

2

Trích xuất từ ​​Tài liệu của Google. Có vẻ như câu trả lời được chấp nhận nhiều nhất về chủ đề này là thiếu một số thông tin quan trọng về cuộc gọi lại của async checkSelfPermission.

Vui lòng xác nhận. Nếu không, tôi sẽ xóa câu trả lời này.

// Here, thisActivity is the current activity 
if (ContextCompat.checkSelfPermission(thisActivity, 
       Manifest.permission.READ_CONTACTS) 
     != PackageManager.PERMISSION_GRANTED) { 

    // Should we show an explanation? 
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, 
      Manifest.permission.READ_CONTACTS)) { 

     // Show an expanation to the user *asynchronously* -- don't block 
     // this thread waiting for the user's response! After the user 
     // sees the explanation, try again to request the permission. 

    } else { 

     // No explanation needed, we can request the permission. 

     ActivityCompat.requestPermissions(thisActivity, 
       new String[]{Manifest.permission.READ_CONTACTS}, 
       MY_PERMISSIONS_REQUEST_READ_CONTACTS); 

     // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an 
     // app-defined int constant. The callback method gets the 
     // result of the request. 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, 
     String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 
       && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

       // permission was granted, yay! Do the 
       // contacts-related task you need to do. 

      } else { 

       // permission denied, boo! Disable the 
       // functionality that depends on this permission. 
      } 
      return; 
     } 

     // other 'case' lines to check for other 
     // permissions this app might request 
    } 
} 
+0

Làm cách nào để yêu cầu quyền dịch vụ? – ajay

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