Android 11 - LocationManager.addProximityAlert 不触发警报
Android 11 - LocationManager.addProximityAlert does not trigger alerts
addProximityAlert
呼叫停止在 Android 11 台设备上触发警报。
我从 Application.onCreate
方法或每当使用以下代码授予 ACCESS_FINE_LOCATION 权限时为特殊位置(针对用户位置计算)调用 addProximityAlert
:
mLocationManager = (LocationManager) mApplicationContext.getSystemService(Context.LOCATION_SERVICE);
if (mLocationManager != null) {
final Criteria criteria = new Criteria();
//criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = mLocationManager.getBestProvider(criteria, true);
if (!TextUtils.isEmpty(provider)) {
mLocationUpdatelistener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
subscribeForProximityAlert(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
final Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider);
if (lastKnownLocation == null) {
try {
mLocationManager.requestSingleUpdate(criteria, mLocationUpdatelistener, Looper.getMainLooper());
} catch (Throwable e) {
e.printStackTrace();
}
} else {
subscribeForProximityAlert(lastKnownLocation);
}
}
}
subscribeForProximityAlert
函数如下(实际是在单点更新成功后调用的——我查过了):
void subscribeForProximityAlert(Location location) {
String id;
double lat;
double lng;
long radius;
// ... compute the params above using the location
final Intent intent = new Intent(ACTION_FILTER);
intent.putExtra("_id", id);
intent.putExtra("_lat", lat);
intent.putExtra("_lng", lng);
intent.putExtra("_rad", radius);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(mApplicationContext, i, intent, 0);
mPendingIntents.add(pendingIntent);
mLocationManager.addProximityAlert(
lat,
lng,
(float) radius,
24 * 60 * 60 * 1000,
pendingIntent
);
}
ACTION_FILTER
com.example.appname.ProximityAlert
正是我在清单中用于订阅 Proximity Alert 广播的值(com.example.appname
是应用程序的包名称):
<application>
<receiver android:name="com.example.appname.ProximityAlertBroadcastReceiver">
<intent-filter>
<action android:name="com.example.appname.ProximityAlert" />
</intent-filter>
</receiver>
</application>
ProximityAlertBroadcastReceiver
可以简单为:
public class ProximityAlertBroadcastReceiver extends BroadcastReceiver {
public ProximityAlertBroadcastReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
}
}
其 onReceive
方法从未在 Android 11 台设备上调用(通过 Lod.d
和 Toast.makeText...show()
调用进行了检查)。不是当应用程序处于 运行 时,不是当它在后台时。不是当我已经在指定点的半径内时,不是当我 entering/exiting.
尝试将 android.permission.ACCESS_BACKGROUND_LOCATION
权限添加到清单(反正 LocationManager.addProximityAlerts
文档中没有关于它的内容)并在应用程序的系统设置中授予权限,但没有帮助。
也尝试将 targetSdkVersion 从 30 降低到 28,但没有帮助。
问题的发生是因为广播接收器的隐式意图,这是针对 Android 8+(SDK 版本 26)的应用程序所禁止的:
https://developer.android.com/about/versions/oreo/background#broadcasts
改变后
final Intent intent = new Intent(ACTION_FILTER);
到
final Intent intent = new Intent(mApplicationContext, ProximityAlertBroadcastReceiver.class);
我开始接收广播了。
更新:最近的 Android 版本(11、12,也许其他)中存在一个错误,这使得地理围栏在某些设备上完全没有响应 non-working在其他设备上,如果此时没有应用主动请求位置:
https://issuetracker.google.com/issues/218335535
addProximityAlert
在引擎盖下创建了一个地理围栏,因此它也受到了影响。
addProximityAlert
呼叫停止在 Android 11 台设备上触发警报。
我从 Application.onCreate
方法或每当使用以下代码授予 ACCESS_FINE_LOCATION 权限时为特殊位置(针对用户位置计算)调用 addProximityAlert
:
mLocationManager = (LocationManager) mApplicationContext.getSystemService(Context.LOCATION_SERVICE);
if (mLocationManager != null) {
final Criteria criteria = new Criteria();
//criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = mLocationManager.getBestProvider(criteria, true);
if (!TextUtils.isEmpty(provider)) {
mLocationUpdatelistener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
subscribeForProximityAlert(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
final Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider);
if (lastKnownLocation == null) {
try {
mLocationManager.requestSingleUpdate(criteria, mLocationUpdatelistener, Looper.getMainLooper());
} catch (Throwable e) {
e.printStackTrace();
}
} else {
subscribeForProximityAlert(lastKnownLocation);
}
}
}
subscribeForProximityAlert
函数如下(实际是在单点更新成功后调用的——我查过了):
void subscribeForProximityAlert(Location location) {
String id;
double lat;
double lng;
long radius;
// ... compute the params above using the location
final Intent intent = new Intent(ACTION_FILTER);
intent.putExtra("_id", id);
intent.putExtra("_lat", lat);
intent.putExtra("_lng", lng);
intent.putExtra("_rad", radius);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(mApplicationContext, i, intent, 0);
mPendingIntents.add(pendingIntent);
mLocationManager.addProximityAlert(
lat,
lng,
(float) radius,
24 * 60 * 60 * 1000,
pendingIntent
);
}
ACTION_FILTER
com.example.appname.ProximityAlert
正是我在清单中用于订阅 Proximity Alert 广播的值(com.example.appname
是应用程序的包名称):
<application>
<receiver android:name="com.example.appname.ProximityAlertBroadcastReceiver">
<intent-filter>
<action android:name="com.example.appname.ProximityAlert" />
</intent-filter>
</receiver>
</application>
ProximityAlertBroadcastReceiver
可以简单为:
public class ProximityAlertBroadcastReceiver extends BroadcastReceiver {
public ProximityAlertBroadcastReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
}
}
其 onReceive
方法从未在 Android 11 台设备上调用(通过 Lod.d
和 Toast.makeText...show()
调用进行了检查)。不是当应用程序处于 运行 时,不是当它在后台时。不是当我已经在指定点的半径内时,不是当我 entering/exiting.
尝试将 android.permission.ACCESS_BACKGROUND_LOCATION
权限添加到清单(反正 LocationManager.addProximityAlerts
文档中没有关于它的内容)并在应用程序的系统设置中授予权限,但没有帮助。
也尝试将 targetSdkVersion 从 30 降低到 28,但没有帮助。
问题的发生是因为广播接收器的隐式意图,这是针对 Android 8+(SDK 版本 26)的应用程序所禁止的: https://developer.android.com/about/versions/oreo/background#broadcasts
改变后
final Intent intent = new Intent(ACTION_FILTER);
到
final Intent intent = new Intent(mApplicationContext, ProximityAlertBroadcastReceiver.class);
我开始接收广播了。
更新:最近的 Android 版本(11、12,也许其他)中存在一个错误,这使得地理围栏在某些设备上完全没有响应 non-working在其他设备上,如果此时没有应用主动请求位置: https://issuetracker.google.com/issues/218335535
addProximityAlert
在引擎盖下创建了一个地理围栏,因此它也受到了影响。