繁体   English   中英

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

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

有很多类似的问题,但似乎没有解决我的问题。

我已经应用了文档中提到的运行时权限,但我仍然遇到运行时错误

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

这是我的完整代码。

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());
}

}

也在清单文件中给予了许可。

因此,这是运行时的错误堆栈跟踪

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位置。 在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)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()异步的 返回时,您还没有权限。 用户甚至没有被问及许可。

您需要在两个地方执行您的位置逻辑:

  • 如果您已经获得许可,请提前预定

  • onRequestPermissionResult() ,如果您请求了权限并且用户授予了权限

此示例应用程序此示例应用程序说明了如何请求运行时权限并将其与LocationClient一起使用。

试试这个顺序,

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

}

我讨厌以下解决方案,但我没有找到更好的解决方案。 如果您从Google API请求位置API并执行: .addApi(LocationServices.API) ,则需要在连接GoogleAPI之前允许位置。

从而,

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

当权限注册商是一个在权限更改时调用回调的类

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

IMMHO,Google应该在内部防范此类案件。 但他们没有。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM