后台服务权限中的 getLastKnownLocation
getLastKnownLocation in a background service permission
我正在尝试恢复设备在由 AlarmManager
触发的 BroadcastReceiver
启动的服务中的最后已知位置,但权限管理系统出现问题,因为即使我在 UI 中动态请求权限,我也会不断收到日志消息 "Notification not allowed"
.
AlarmManager
/BroadcastReceiver
组合的目标是定期调用由用户位置决定的 REST API。
服务代码
服务的 onHandleIntent
方法由 WakefulBroadcastReceiver
和 startWakefulService
调用
@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值...)
我正在尝试恢复设备在由 AlarmManager
触发的 BroadcastReceiver
启动的服务中的最后已知位置,但权限管理系统出现问题,因为即使我在 UI 中动态请求权限,我也会不断收到日志消息 "Notification not allowed"
.
AlarmManager
/BroadcastReceiver
组合的目标是定期调用由用户位置决定的 REST API。
服务代码
服务的 onHandleIntent
方法由 WakefulBroadcastReceiver
和 startWakefulService
@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值...)