这太奇怪了。我们都知道,如果<uses-sdk android:targetSdkVersion="23"/>
设置为23+,则除了在清单中声明<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
之外,还必须要求运行时权限。
多年来一直没有问题。现在,问题在于,当我将targetSdkVersion设置为“ 26”时,LocationManager不再起作用!并抛出此错误:
"gps" location provider requires ACCESS_FINE_LOCATION permission
我在应用程序中唯一更改的是targetsdkversion从23变为26,它破坏了应用程序!有什么想法吗?
答案 0 :(得分:0)
尝试使用完整的解决方案
在清单中添加权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
在onCreate()
中进行
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkAndroidVersion();
}
此方法checkAndroidVersion();
public void checkAndroidVersion() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkAndRequestPermissions()) {
buildClient();
mGoogleApiClient.connect();
} else
{
}
} else {
if (checkPlayServices()) {
// Building the GoogleApi client
buildClient();
mGoogleApiClient.connect();
}
// write your logic here
}
}
此方法checkAndRequestPermissions()
public boolean checkAndRequestPermissions() {
int location = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (location != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(MainActivity.this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
处理onRequestPermission()
方法
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
Log.d("in main on request", "Permission callback called-------");
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<>();
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
// Fill with actual results from user
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for both permissions
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.d("in main on request", "location services permission granted");
// process the normal flow
//else any one or both the permissions are not granted
buildClient();
mGoogleApiClient.connect();
} else {
Log.d("in fragment on request", "Some permissions are not granted ask again ");
//permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
// // shouldShowRequestPermissionRationale will return true
//show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) {
showDialogOK("Location services services are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
Toast.makeText(MainActivity.this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
.show();
// //proceed with logic by disabling the related features or quit the app.
}
}
}
}
}
}
public void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
声明此方法buildClient()
public void buildClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
句柄onStop()
@Override
public void onStop() {
super.onStop();
if (mGoogleApiClient != null) {
if (mGoogleApiClient.isConnected() && mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
}
}
声明此方法checkPlayServices()
/**
* Method to verify google play services on the device
*/
public boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(MainActivity.this,
"This device is not supported.", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
覆盖Google api方法
@Override
public void onConnected(@Nullable Bundle bundle) {
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;
}
startLocationUpdates();
mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLocation == null) {
startLocationUpdates();
}
if (mLocation != null) {
double latitude = mLocation.getLatitude();
double longitude = mLocation.getLongitude();
} else {
// Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
}
/**
* This library works in release mode only with the same JKS key used for
* your Previous Version
*/
}
protected void startLocationUpdates() {
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(5000)
.setFastestInterval(5000);
// Request location updates
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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
Log.d("reque", "--->>>>");
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
try {
if (checkAndRequestPermissions()) {
buildClient();
mGoogleApiClient.connect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onLocationChanged(Location location) {
current_location = location;
SharedPrefsUtils.setStringPreference(MainActivity.this, "user_current_latitude", current_location.getLatitude() + "");
SharedPrefsUtils.setStringPreference(MainActivity.this, "user_current_longitude", current_location.getLongitude() + "");
System.out.println("sjkbd jdsbj");
}
在
中Activity
或fragment
private GoogleApiClient mGoogleApiClient;
private Location mLocation;
private LocationManager locationManager;
private LocationRequest mLocationRequest;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
答案 1 :(得分:0)
好的,我可以解决问题,如果其他人遇到类似的问题,我也会在这里进行解释。我应该补充一点,虽然问题已得到解决,但感觉就像是Android上的错误或缺少文档。
由于一些内部项目原因,我正在请求以下位置权限:
PackageInfo packageInfo = pm.getPackageInfo(_activity.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] requestedPermissions = null;
if (packageInfo != null)
{
requestedPermissions = packageInfo.requestedPermissions;
if (requestedPermissions.length > 0)
{
List<String> requestedPermissionsList = Arrays.asList(requestedPermissions);
_requestedPermissionsArrayList = new ArrayList<String>();
_requestedPermissionsArrayList.addAll(requestedPermissionsList);
}
}
for(int i=0; i < _requestedPermissionsArrayList.size(); i++)
{
if(_requestedPermissionsArrayList.get(i).equals(Manifest.permission.ACCESS_FINE_LOCATION) || // api level 1
_requestedPermissionsArrayList.get(i).equals(Manifest.permission.ACCESS_COARSE_LOCATION) // api level 1
)
{
isFound = true;
ActivityCompat.requestPermissions(_activity, new String[]{
_requestedPermissionsArrayList.get(i)
}, ExConsts.MY_PERMISSIONS_REQUEST);
break;
}
}
使用此设置,清单中的权限顺序很重要!当我有:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
它不起作用,但是当我切换他们的订单时,它起作用了。
最后,我如何解决该问题?像下面一样,我提到了两个权限名称
ActivityCompat.requestPermissions(_activity, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
}
现在,无论清单中的权限顺序如何,它始终可以正常工作。欢呼。