有很多类似的问题,但似乎都没有解决我的问题。
我已经应用了文档中提到的运行时权限,但我仍然在行上遇到运行时错误
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) 在com.google.android.gms.internal.zzed.zzb(未知来源) 在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.zzccc.zza(未知来源) 在com.google.android.gms.internal.zzbay.zzb(未知来源) 在com.google.android.gms.internal.zzbca.zze(未知来源) 在com.google.android.gms.internal.zzbcx.zze(未知来源) 在com.google.android.gms.internal.zzbcp.zze(未知来源) 在com.google.android.gms.internal.zzccb.requestLocationUpdates(未知来源) 在com.example.ashutosh.location.MainActivity.onConnected(MainActivity.java:122) 在com.google.android.gms.common.internal.zzac.zzn(未知来源) 在com.google.android.gms.internal.zzbcp.zzm(未知来源) 在com.google.android.gms.internal.zzbcd.zzpY(未知来源) 在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.os.Handler.dispatchMessage(Handler.java:102) 在android.os.Looper.loop(Looper.java:152) 在android.app.ActivityThread.main(ActivityThread.java:5497) at java.lang.reflect.Method.invoke(Native Method) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
答案 0 :(得分:2)
requestPermissions()
异步。返回时,您还没有权限。用户甚至没有询问有关权限。
您需要在两个地方执行您的位置逻辑:
如果您已经获得许可,请事先预先
在onRequestPermissionResult()
中,如果您请求了权限并且用户授予了权限
This sample app和this sample app说明了如何请求运行时权限并将其与LocationClient
一起使用。
答案 1 :(得分:0)
尝试此序列,
@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
}
}
答案 2 :(得分:0)
我讨厌以下解决方案,但我没有找到更好的方法。
如果您从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应该在内部防范这种情况。但他们没有。