后台服务权限中的 getLastKnownLocation

getLastKnownLocation in a background service permission

我正在尝试恢复设备在由 AlarmManager 触发的 BroadcastReceiver 启动的服务中的最后已知位置,但权限管理系统出现问题,因为即使我在 UI 中动态请求权限,我也会不断收到日志消息 "Notification not allowed".

AlarmManager/BroadcastReceiver 组合的目标是定期调用由用户位置决定的 REST API。

服务代码

服务的 onHandleIntent 方法由 WakefulBroadcastReceiverstartWakefulService

调用
@Override
protected void onHandleIntent(Intent intent) {
    if (BuildConfig.DEBUG) Log.d(TAG, "Handling intent");

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.cancelAll();

    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_COARSE);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setSpeedRequired(false);
    criteria.setCostAllowed(true);

    String provider = locationManager.getBestProvider(criteria, true);
    boolean localizationPermitted = ContextCompact.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED;

    if (localizationPermitted) {
        Location lastLocation = locationManager.getLastKnownLocation(provider);
        if (BuildConfig.DEBUG) Log.d(TAG, "Location: " +lastLocation.toString() );

        // stuff that needs the location

    } else {
        if (BuildConfig.DEBUG) Log.e(TAG, "Localization not allowed");
    }
}

清单权限

我已经在 AndroidMainfest.xml 文件中声明了权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...">
    ...
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    ...
</manifest>

动态权限

在启动触发服务的警报之前,我在应用程序的 Fragment 中请求权限:

boolean gotPermission = ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION)
        == PackageManager.PERMISSION_GRANTED;


if (gotPermission){
    if (BuildConfig.DEBUG) Log.v(TAG, "Got the permission");
    // Schedule the alarm
} else {
    ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
}

在对话框的回调中我得到了 "Permission granted":

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (permissions.length == 1 &&
            permissions[0].equals(android.Manifest.permission.ACCESS_COARSE_LOCATION) &&
            grantResults[0] == PackageManager.PERMISSION_GRANTED) {

        if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (BuildConfig.DEBUG) Log.d(TAG, "Permission granted");
        }
    } else {
        if (BuildConfig.DEBUG) Log.e(TAG, "Permission not granted");
    }
}
boolean localizationPermitted = ContextCompact.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED;

如果授予权限(!=),这将是true。将其更改为:

boolean localizationPermitted = ContextCompact.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;

(我真的希望他们刚刚使用了来自checkSelfPermission()boolean return值...)