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.dToast.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 在引擎盖下创建了一个地理围栏,因此它也受到了影响。