【问题标题】:Impossible to remove proximity alert无法移除接近警报
【发布时间】:2015-09-24 16:17:05
【问题描述】:

用户有一个开关来激活或停用接近警报。

当用户激活此开关时,接近警报将以通知的方式显示。使用操作栏上的此通知,如果用户将开关更改为“停用”模式,则通知会消失。它工作正常。

但我的问题是这样的:

我激活了警报,但在那一刻它没有显示任何内容,因为我不在 POI 附近。我改变了主意,现在我不想要任何警报,所以我将开关更改为“停用”模式(任何通知都出现在操作栏上)。

但是,当我打开“停用”模式时,当我靠近 POI 时,警报会出现在操作栏上,我不知道为什么。 我将 removeProximityAlert 与每个 POI 的待处理意图的值一起使用。

要激活警报:

public void activateAlerts() {

    Database db = new Database(getApplicationContext());
    Cursor cursor = db.getPois();

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


    while (cursor.moveToNext()) {

        ...
        Intent intent = new Intent(PROX_ALERT_INTENT);

        String idSubstring = id.substring(7);
        int lastDigitsOfID = Integer.parseInt(idSubstring);
        PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), lastDigitsOfID, intent, PendingIntent.FLAG_ONE_SHOT);

        try {
            locationManager.addProximityAlert(latitude, longitude, Utils.RADIOALERTS, -1, pi);
        } catch (Exception e) {
            Log.e(getClass().getSimpleName().toString(), e.toString());
        }
        notifications.add(new NotificationObject(cursor.getString(idIndex), lastDigitsOfID));
    }
    db.addNotifications(notifications);
}

要停用警报:

public void deactivateAlerts() {

    Database db = new Database(getApplicationContext());
    Cursor cursor = db.getIdPendingIntents();

    int idPendingIntentIndex = cursor.getColumnIndex("id_pendingintent");
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    while (cursor.moveToNext()) {
        Intent intent = new Intent(PROX_ALERT_INTENT); 
        PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
                cursor.getInt(idPendingIntentIndex), intent, 0);
        locationManager.removeProximityAlert(pendingIntent);
    }

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

我读过这篇文章:

Post1

Post2

Post3

【问题讨论】:

    标签: android notifications alert android-pendingintent proximity


    【解决方案1】:

    您的问题是PendingIntent.FLAG_ONE_SHOT 的使用。这没有很好的记录,但是如果您删除该标志,它应该可以工作。

    当您使用FLAG_ONE_SHOT 创建PendingIntent 时,Android 不会跟踪此PendingIntent(因为它只允许使用一次)。在我看来,这是一个“优化”,实际上是一个 Android 错误 :-(

    当您调用removeProximityAlert() 并将PendingIntent 传递给它时,该方法中的代码会尝试取消所有具有匹配 PendingIntent 的接近警报。由于 Android 不会跟踪使用 FLAG_ONE_SHOT 创建的 PendingIntents,因此“匹配”代码永远不会找到您的接近警报,因此不会取消它。

    【讨论】:

    • 如果这能解决您的问题,请告诉我,我会添加更多解释。我目前无法执行此操作。
    • 我正在测试而不是 PendingIntent.FLAG_ONE_SHOT,值为 0。从工作办公室看来,它工作得很好(一段时间后我会在真实情况下对其进行测试),但是,你能解释一下为什么 FLAG_ONE_SHOT 不能正常工作吗?我不知道 =(
    • 为我的回答添加了解释。恕我直言,这是一个 Android 错误。
    • 另见stackoverflow.com/a/29780579/769265 问题有所不同,但FLAG_ONE_SHOT 的行为在这种情况下也会造成混乱。
    【解决方案2】:

    真的一样吗?

    激活:

    PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), lastDigitsOfID, intent, PendingIntent.FLAG_ONE_SHOT);
    

    停用:

    PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),cursor.getInt(idPendingIntentIndex), intent, 0);
    

    请查看intentEquals() 方法,并确保您的意图与此处描述的标准相同。

    【讨论】:

    • 是的,它是相同的值...我将值存储在本地数据库中(激活),然后加载每个 POI 的值(停用光标)。我用日志检查过,是的,它具有相同的值。
    • 我已经用该方法测试了代码,它为意图返回“true”......它们是相同的 =(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多