简体   繁体   English

客户端必须具有ACCESS_FINE_LOCATION权限才能请求PRIORITY_HIGH_ACCURACY位置运行时错误

[英]Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations runtime error

There are plenty of similar questions asked but none seem to solve my problem. 有很多类似的问题,但似乎没有解决我的问题。

I have applied run time permissions as mentioned on the documentation, still I am getting a run time error on the line 我已经应用了文档中提到的运行时权限,但我仍然遇到运行时错误

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

Here is my complete code. 这是我的完整代码。

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

private static final String TAG ="hello" ;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;


public Location mLastLocation=null;


public final int MY_PERMISSIONS_REQUEST_COARSE_LOCATION=0;

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

    if (mGoogleApiClient==null){
        mGoogleApiClient= new GoogleApiClient.Builder(this)

                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    mLocationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(10 * 100)        // 10 seconds, in milliseconds
            .setFastestInterval( 1* 100); // 1 second, in milliseconds

    }









@Override
public void onConnected(@Nullable Bundle bundle) {


    int permissionCheck = ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    int permissionCheck1 = ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION);
    if (permissionCheck != PackageManager
            .PERMISSION_GRANTED && permissionCheck1 != PackageManager.PERMISSION_GRANTED) {

        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an explanation 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(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_COARSE_LOCATION);


        }
    }


    mLastLocation=LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (mLastLocation != null) {
        TextView mLatitudeText =(TextView)findViewById(R.id.textView);
        TextView mLongitudeText =(TextView)findViewById(R.id.textView2);

        mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
        mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));

        Log.i("Location Info", "Location achieved!");

    } else {



        Log.i("Location Info", "No location :(");

    }


    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);//error here!!






}



@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

@Override
protected void onResume() {
    mGoogleApiClient.connect();
    super.onResume();

}

@Override
protected void onPause() {
    mGoogleApiClient.disconnect();
    super.onPause();
}



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

                Log.i("Message","Got full permission");



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



}


@Override
public void onLocationChanged(Location location)
{
    Log.i("Location Info", "Location is changed Bitchh :(");
    handleNewLocation(location);
}

private void handleNewLocation(Location location) {
    Log.d(TAG, location.toString());
}

} }

Also I have given permission in the manifest file. 也在清单文件中给予了许可。

So, this is the error stack trace on run time 因此,这是运行时的错误堆栈跟踪

10-24 17:13:02.857 2224-2379/com.example.ashutosh.location E/AbstractTracker: Can't create handler inside thread that has not called Looper.prepare() 0-24 17:13:03.184 2224-2224/com.example.ashutosh.location E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.ashutosh.location, PID: 2224 java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations. 10-24 17:13:02.857 2224-2379 / com.example.ashutosh.location E / AbstractTracker:无法在未调用Looper.prepare()的线程内创建处理程序0-24 17:13:03.184 2224-2224 /com.example.ashutosh.location E / AndroidRuntime:FATAL EXCEPTION:main进程:com.example.ashutosh.location,PID:2224 java.lang.SecurityException:客户端必须具有ACCESS_FINE_LOCATION权限才能请求PRIORITY_HIGH_ACCURACY位置。 at android.os.Parcel.readException(Parcel.java:1620) at android.os.Parcel.readException(Parcel.java:1573) at com.google.android.gms.internal.zzed.zzb(Unknown Source) at com.google.android.gms.internal.zzcda.zza(Unknown Source) at com.google.android.gms.internal.zzcdd.zza(Unknown Source) at com.google.android.gms.internal.zzcdj.zza(Unknown Source) at com.google.android.gms.internal.zzccc.zza(Unknown Source) at com.google.android.gms.internal.zzbay.zzb(Unknown Source) at com.google.android.gms.internal.zzbca.zze(Unknown Source) at com.google.android.gms.internal.zzbcx.zze(Unknown Source) at com.google.android.gms.internal.zzbcp.zze(Unknown Source) at com.google.android.gms.internal.zzccb.requestLocationUpdates(Unknown Source) at com.example.ashutosh.location.MainActivity.onConnected(MainActivity.java:122) at com.google.android.gms.common.internal.zzac.zzn(Unknown Source) at com.google.android.gms.internal.zzbcp.zzm(Unknown Source) at com.google.android.gms.internal.zzbcd.zzpY(Unknown Sou 在android.os.Parcel.readException(Parcel.java:1620)的android.os.Parcel.readException(Parcel.java:1573)at com.google.android.gms.internal.zzed.zzb(Unknown Source)at com .google.android.gms.internal.zzcda.zza(未知来源)位于com.google.android.gms.internal.zzcdd.zza(未知来源)com.google.android.gms.internal.zzcdj.zza(未知)来自com.google.android.gms.internal.zz上的com.google.android.gms.internal.zzccc.zza(未知来源)com.google.android.gms.internal.zz .zze(未知来源)com.google.android.gms.internal.zzbcx.zze(未知来源)com.google.android.gms.internal.zzbcp.zze(未知来源)com.google.android.gms .internal.zzccb.requestLocationUpdates(未知来源)位于com.google.ashutosh.location.MainActivity.onConnected(MainActivity.java:122)com.google.android.gms.common.internal.zzac.zzn(未知来源)at at com.google.android.gms.internal.zzbcp.zzm(未知来源)com.google.android.gms.internal.zzbcd.zzpY(Unknown Sou) rce) at com.google.android.gms.internal.zzbcd.onConnected(Unknown Source) at com.google.android.gms.internal.zzbcx.onConnected(Unknown Source) at com.google.android.gms.internal.zzbbi.onConnected(Unknown Source) at com.google.android.gms.common.internal.zzaa.onConnected(Unknown Source) at com.google.android.gms.common.internal.zzn.zzrj(Unknown Source) at com.google.android.gms.common.internal.zze.zzs(Unknown Source) at com.google.android.gms.common.internal.zzi.zzrk(Unknown Source) at com.google.android.gms.common.internal.zzh.handleMessage(Unknown Source) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:152) at android.app.ActivityThread.main(ActivityThread.java:5497) 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) rce)com.google.android.gms.internal.zzbcd.onConnected(未知来源)com.google.android.gms.internal.zzbcx.onConnected(未知来源)com.google.android.gms.internal.zzbbi .onConnected(未知来源)位于com.google.android.gms.common.internal.zzaa.onConnected(未知来源)com.google.android.gms.common.internal.zzn.zzrj(未知来源)com.google .android.gms.common.internal.zze.zzs(未知来源)com.google.android.gms.common.internal.zzi.zzrk(未知来源)com.google.android.gms.common.internal.zzh .handleMessage(未知来源)位于android.app.AooT.Thread.main上的android.os.Handler.dispatchMessage(Handler.java:102)android.os.Looper.loop(Looper.java:152)(ActivityThread.java:5497 )com.android.internal.os.ZygoteInit.main中的com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)中的java.lang.reflect.Method.invoke(Native Method)(ZygoteInit)的.java:616)

requestPermissions() is asynchronous . requestPermissions()异步的 When it returns, you do not yet have permission. 返回时,您还没有权限。 The user has not even been asked about the permission. 用户甚至没有被问及许可。

You need to do your location logic in two places: 您需要在两个地方执行您的位置逻辑:

  • Up front, if you have permission already 如果您已经获得许可,请提前预定

  • In onRequestPermissionResult() , if you requested permissions and the user granted them onRequestPermissionResult() ,如果您请求了权限并且用户授予了权限

This sample app and this sample app illustrate how to request runtime permissions and use them with LocationClient . 此示例应用程序此示例应用程序说明了如何请求运行时权限并将其与LocationClient一起使用。

Try this sequence, 试试这个顺序,

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


int permissionCheck = ContextCompat.checkSelfPermission(this,
        Manifest.permission.ACCESS_FINE_LOCATION);
int permissionCheck1 = ContextCompat.checkSelfPermission(this,
        Manifest.permission.ACCESS_COARSE_LOCATION);
if (permissionCheck != PackageManager
        .PERMISSION_GRANTED && permissionCheck1 != PackageManager.PERMISSION_GRANTED) {

    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.ACCESS_FINE_LOCATION)) {

        // Show an explanation 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(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                MY_PERMISSIONS_REQUEST_COARSE_LOCATION);


    }
} else {

if (mGoogleApiClient==null){
    mGoogleApiClient= new GoogleApiClient.Builder(this)

            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}

mLocationRequest = LocationRequest.create()
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
        .setInterval(10 * 100)        // 10 seconds, in milliseconds
        .setFastestInterval( 1* 100); // 1 second, in milliseconds
        }
}



@Override public void onConnected(@Nullable Bundle bundle) {
mLastLocation=LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
    TextView mLatitudeText =(TextView)findViewById(R.id.textView);
    TextView mLongitudeText =(TextView)findViewById(R.id.textView2);
    mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
    mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
    Log.i("Location Info", "Location achieved!");
} else {
    Log.i("Location Info", "No location :(");
}

LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);//error here!!
}


@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
    case  MY_PERMISSIONS_REQUEST_COARSE_LOCATION :{
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.i("Message","Got full permission");
        if (mGoogleApiClient==null){
         mGoogleApiClient= new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
        }
        mLocationRequest = LocationRequest.create()
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
        .setInterval(10 * 100)        // 10 seconds, in milliseconds
        .setFastestInterval( 1* 100); // 1 second, in milliseconds
        } 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
}

} }

I hate the following solution but I did not find any better. 我讨厌以下解决方案,但我没有找到更好的解决方案。 If you request location API from Google API's and you do: .addApi(LocationServices.API) , you need to have location permitted before connecting GoogleAPI's. 如果您从Google API请求位置API并执行: .addApi(LocationServices.API) ,则需要在连接GoogleAPI之前允许位置。

Thus, 从而,

fun checkPermission(context:Context, permission:Name) : Boolean =
    ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED

fun isLocationPermissionGranted() = checkPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)

if (isLocationPermissionGranted()) {
     googleApiBuilder.connect()
} else {
     MyPermissionChangeRegistrar().instance.register { 
          if (isLocationPermissionGranted()) {
               googleApiBuilder.connect()
          }
     } 
}

When the Permission registrar is a class that calls a callback when a permission changed 当权限注册商是一个在权限更改时调用回调的类

class SomeActivity: Activity() {
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        MyPermissionChangeRegistrar.callCallbacks()
    }
}

IMMHO, Google ought to protect against such cases internally. IMMHO,Google应该在内部防范此类案件。 But they don't. 但他们没有。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android权限ACCESS_FINE_LOCATION始终被拒绝 - Android Permission ACCESS_FINE_LOCATION is always denied 无法在Android中获得ACCESS_FINE_LOCATION权限 - Can't get ACCESS_FINE_LOCATION permission in android 错误:java.lang.SecurityException:我的位置需要权限 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION - ERROR:java.lang.SecurityException: my location requires permission ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION 权限是否包括 ACCESS_COARSE_LOCATION 权限 - Does ACCESS_FINE_LOCATION permission include ACCESS_COARSE_LOCATION permissons 由以下原因引起:java.lang.SecurityException:“被动”位置提供者需要ACCESS_FINE_LOCATION权限 - Caused by: java.lang.SecurityException: “passive” location provider requires ACCESS_FINE_LOCATION permission java.lang.SecurityException:“被动”位置提供者需要API级别26的ACCESS_FINE_LOCATION权限 - java.lang.SecurityException: “passive” location provider requires ACCESS_FINE_LOCATION permission on API level 26 Android WifiManager getScanResult抱怨虽然声明了权限,但需要ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION权限 - Android WifiManager getScanResult complains Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission although declared permission java.lang.SecurityException:提供者gps需要ACCESS_FINE_LOCATION权限 - java.lang.SecurityException: Provider gps requires ACCESS_FINE_LOCATION permission Android“gps需要ACCESS_FINE_LOCATION”错误,即使我的清单文件包含这个 - Android "gps requires ACCESS_FINE_LOCATION" error, even though my manifest file contains this 如何在运行时请求位置权限 - How to request Location Permission at runtime
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM