Как создать другой pendingintent, чтобы filterEquals () возвращало false? - PullRequest
20 голосов
/ 21 сентября 2011

Я использую AlarmManager для настройки повторяющихся намерений, но это вызвало небольшие проблемы, поэтому надеюсь, что кто-нибудь сможет помочь.

Основная информация

Есть 2 ожидающих намерения. Один работает на 1000, а другой работает на 2000 каждый день. Каждый содержит идентификатор строки из базы данных для целей идентификации. Код выглядит примерно так:

Intent i = new Intent(mContext, ScheduleReceiver.class);
i.putExtra(RuleDBAdapter.KEY_ROWID, (int)taskId);
PendingIntent pi =PendingIntent.getBroadcast(...);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi); 

Удаление:

Проблема в том, что нам нужно удалить один из них. Правильный способ удалить ожидающее намерение состоит в том, чтобы установить идентичное и затем вызвать отмену из AlarmManager.

Документация Android:

отмены публичного аннулирования (операция PendingIntent)
Удалите все тревоги с соответствующим Намерением. Любой сигнал тревоги любого типа, у которого Intent соответствует этому (как определено filterEquals (Intent)), будет отменен.

public boolean filterEquals (Intent other)
Определите, являются ли два намерения одинаковыми для целей разрешения намерений (фильтрации). То есть, если их действие, данные, тип, класс и категории совпадают. не сравнивает никакие дополнительные данные , включенные в намерения.

Таким образом, в приведенном выше примере, если я сделаю идентичное намерение, а затем отменим, оба вышеуказанных намерения будут отменены, поскольку они принадлежат к одному и тому же классу / тому же действию и т. Д. (За исключением «дополнительного») данные являются rowId, но filterEquals не заботятся о дополнительных данных).

Есть ли обходной путь для этого?

Ответы [ 5 ]

23 голосов
/ 21 сентября 2011

Вы можете попробовать использовать параметр requestCode при создании ожидаемого намерения:

PendingIntent pi =PendingIntent.getBroadcast(mContext, yourUniqueDatabaseId,i,PendingIntent.FLAG_ONE_SHOT);

Это должно создать намерение, уникальное для соответствующих целей.

3 голосов
/ 21 сентября 2011

public boolean filterEquals (Intent other) сравнивает действие, данные, тип, пакет, компонент и категории, но не сравнивает дополнительные, поэтому разница между дополнительными элементами не может различить Intents. Попробуйте установить разные данные для этих Intents, данные могут быть незначительными Uris.

Попробуйте прочитать исходный код, чтобы получить больше информации.

1 голос
/ 03 августа 2012

Попытка ввести фиктивное действие в намерение.Например.

myIntent.setAction(""+System.currentTimeMillis());

Это приведет к тому, что filterEquals вернет false.

Мне понадобилось аналогичное решение для отправки смс-уведомлений с нескольких номеров, чтобы позволить уведомлению запускать средство просмотра потоков смс с разныминомера.

0 голосов
/ 09 мая 2013

В моем случае у меня не было хорошего способа сгенерировать уникальный ключ для моих ожидающих намерений, поэтому я добавил пользовательские данные в сгенерированное намерение.

Как только вы начнете заполнять атрибут данных, вы должны не забыть добавить параметр данных в фильтр намерений в манифесте Android. Если вы этого не сделаете, не вызовет ваш пользовательский приемник.

Примеры:

Намерение

    Intent intent = new Intent(reminderFire);
intent.addCategory(reminderCategory);
Uri.Builder builder = new Uri.Builder();
builder.scheme(context.getString(R.string.scheme));
builder.authority(context.getString(R.string.intent_filter_reminder_host));
builder.appendQueryParameter("oid", Reminder.getOid());
intent.setData(builder.build());

Запись AndroidManifest

<receiver 
    android:name=".client.MyReminder"
    android:enabled="true"
>
    <intent-filter>
        <action android:name="com.example.client.reminder.fire"/>
        <action android:name="com.example.client.reminder.category"/>
        <data
            android:host="@string/intent_filter_reminder_host"
            android:scheme="@string/scheme" />
    </intent-filter>
</receiver>

Делая это, вы также можете проверить уникальность в намерении, прежде чем оно будет добавлено в качестве ожидающего намерения, что полезно, если вы проводите модульное тестирование.

0 голосов
/ 22 марта 2013

Поместите идентификатор задачи и метку времени в действие намерения.Таким образом, вы связываете ожидающее намерение с идентификатором задачи, и намерения по-прежнему будут отличаться с точки зрения фильтрации.

intent.setAction("ACTION_" + taskId + "_" + currentTimestamp);
...