gpt4 book ai didi

java - 如何在运行时请求位置权限

转载 作者:IT老高 更新时间:2023-10-28 20:32:19 30 4
gpt4 key购买 nike

在 list 文件中,我添加了粗略和精细的权限,当我在装有 Android 6 的设备上运行时,什么也没有发生!我试试一切,但无法获取位置更新...

我做错了什么?

public class MainActivity extends AppCompatActivity implements LocationListener {

LocationManager locationManager;
String provider;

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

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

provider = locationManager.getBestProvider(new Criteria(), false);

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location location = locationManager.getLastKnownLocation(provider);

if (location != null) {

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

} else {

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

}

}


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

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(provider, 400, 1, this);

}

@Override
protected void onPause() {
super.onPause();

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.removeUpdates(this);

}

@Override
public void onLocationChanged(Location location) {

Double lat = location.getLatitude();
Double lng = location.getLongitude();

Log.i("Location info: Lat", lat.toString());
Log.i("Location info: Lng", lng.toString());

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}

public void getLocation(View view) {

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location location = locationManager.getLastKnownLocation(provider);

onLocationChanged(location);


}

}

最佳答案

您需要在运行时实际请求位置权限(请注意代码中说明这一点的注释)。

更新了 Kotlin 和 API 31 (Android 12) 的后台位置:

从 API 30 开始,后台位置必须单独请求。此示例使用 targetSdk 31compileSdk 31。请注意,可以将后台位置请求与 API 29 上的主要位置请求 bundle 在一起,但要做到这一点,您需要维护三个单独的代码路径。
将其分解为对 29 及以上的请求更容易。

确保在应用级别 gradle(撰写本文时为 18.0.0)中包含最新的定位服务:

implementation "com.google.android.gms:play-services-location:18.0.0"

在 list 中包含位置权限:

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

这是一个简化的示例,可以处理大多数情况,但以简化的方式。在用户选择“不再询问”的情况下,在下次启动应用程序时,它将打开用户手动启用权限的设置。

完整的 Activity 代码:

import android.Manifest
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.location.*


class MainActivity : AppCompatActivity() {

private var fusedLocationProvider: FusedLocationProviderClient? = null
private val locationRequest: LocationRequest = LocationRequest.create().apply {
interval = 30
fastestInterval = 10
priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
maxWaitTime = 60
}

private var locationCallback: LocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
val locationList = locationResult.locations
if (locationList.isNotEmpty()) {
//The last location in the list is the newest
val location = locationList.last()
Toast.makeText(
this@MainActivity,
"Got Location: " + location.toString(),
Toast.LENGTH_LONG
)
.show()
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

fusedLocationProvider = LocationServices.getFusedLocationProviderClient(this)

checkLocationPermission()
}

override fun onResume() {
super.onResume()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED
) {

fusedLocationProvider?.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
}
}

override fun onPause() {
super.onPause()
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
== PackageManager.PERMISSION_GRANTED
) {

fusedLocationProvider?.removeLocationUpdates(locationCallback)
}
}

private fun checkLocationPermission() {
if (ActivityCompat.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 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.
AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton(
"OK"
) { _, _ ->
//Prompt the user once explanation has been shown
requestLocationPermission()
}
.create()
.show()
} else {
// No explanation needed, we can request the permission.
requestLocationPermission()
}
} else {
checkBackgroundLocation()
}
}

private fun checkBackgroundLocation() {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
requestBackgroundLocationPermission()
}
}

private fun requestLocationPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
),
MY_PERMISSIONS_REQUEST_LOCATION
)
}

private fun requestBackgroundLocationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_BACKGROUND_LOCATION
),
MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION
)
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_PERMISSIONS_REQUEST_LOCATION
)
}
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
when (requestCode) {
MY_PERMISSIONS_REQUEST_LOCATION -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
fusedLocationProvider?.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)

// Now check background location
checkBackgroundLocation()
}

} else {

// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()

// Check if we are in a state where the user has denied the permission and
// selected Don't ask again
if (!ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
) {
startActivity(
Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", this.packageName, null),
),
)
}
}
return
}
MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
fusedLocationProvider?.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)

Toast.makeText(
this,
"Granted Background Location Permission",
Toast.LENGTH_LONG
).show()
}
} else {

// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()
}
return

}
}
}

companion object {
private const val MY_PERMISSIONS_REQUEST_LOCATION = 99
private const val MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION = 66
}
}

在 Android 10 (API 29) 上,用户可以选择在初始位置请求后授予后台位置:

enter image description here

enter image description here

在 Android 12 (API 31) 上它会执行相同的操作,但界面不同:

enter image description here

enter image description here

enter image description here

Java 中的原始答案:

这里是请求位置权限的测试和工作代码。

把这段代码放到Activity中:

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

public boolean checkLocationPermission() {
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 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.
new AlertDialog.Builder(this)
.setTitle(R.string.title_location_permission)
.setMessage(R.string.text_location_permission)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();


} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}

@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_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
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {

//Request location updates:
locationManager.requestLocationUpdates(provider, 400, 1, this);
}

} else {

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

}
return;
}

}
}

然后在onCreate()中调用checkLocationPermission()方法:

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

//.........

checkLocationPermission();
}

然后,您可以完全按照问题中的方式使用 onResume()onPause()

这是一个更简洁的精简版:

@Override
protected void onResume() {
super.onResume();
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {

locationManager.requestLocationUpdates(provider, 400, 1, this);
}
}

@Override
protected void onPause() {
super.onPause();
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {

locationManager.removeUpdates(this);
}
}

关于java - 如何在运行时请求位置权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40142331/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com