2011-09-21 6 views
20

Sto usando AlarmManager per impostare intenti ripetuti ma ha causato alcuni piccoli problemi quindi spero che qualcuno possa aiutare.Come creare diversi suggerimenti in sospeso in modo che filterEquals() restituisca false?

Sommario

Ci sono 2 intenti in attesa. Una corre a 1000 e un'altra corre a 2000 ogni giorno. Ciascuno contiene un ID riga dal database a scopo di identificazione. Il codice simile a questa:

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); 

Soppressione:

Il problema è quando abbiamo bisogno di eliminare uno di loro. Il modo corretto per eliminare un intent in sospeso è impostarne uno identico e quindi chiamare cancel da AlarmManager.

Android Documentazione:

public void cancel (PendingIntent operation)
Rimuovere eventuali allarmi con un intento di corrispondenza. Qualsiasi allarme, di qualsiasi tipo, di cui Intent corrisponde a questo (come definito da filterEquals (Intent)), verrà annullato.

public boolean filterEquals (Intent other)
determinare se due intenti sono uguali ai fini della risoluzione intenti (filtraggio). Cioè, se la loro azione, i dati, il tipo, la classe e le categorie sono gli stessi. Questo non confronta alcun dato aggiuntivo incluso negli intenti.

Così, nell'esempio di cui sopra, se faccio un intento identico quindi annullare, sia degli intenti di cui sopra otterrà annullati, perché sono dalla stessa classe/stessa azione etc (ad eccezione dei dati "extra" è rowId ma filterEquals non si preoccupa dei dati extra).

C'è qualche soluzione per questo?

risposta

23

Si potrebbe provare a utilizzare il parametro requestCode quando si crea il vostro intento in attesa:

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

Questo dovrebbe creare un intento che è unico per scopi corrispondenti a ..

+0

grazie! prob che funzionerà. Non sapevo che è semplice come questo. :) – markbse

+0

Vorrei che aggiornassero la documentazione, perché dire "non usato" per la requestCode è davvero intimidatorio quando si cerca di far funzionare qualcosa. –

+0

Attenzione: requestCode è definito come int mentre normalmente gli ID di riga (sqlite) sono lunghi. – HaimS

2

filterEquals booleani pubblici (Intent altro) confrontare il azione, dati, tipo, pacchetto, componente e categorie, ma non confrontare l'extra, quindi la differenza tra gli extra non può distinguere gli Intenti. Prova a impostare dati diversi per questi Intenti, i dati potrebbero essere insignificanti di Uris.

Prova a leggere il codice sorgente per ottenere maggiori informazioni.

1

Provare a mettere un'azione fittizia nell'intento. Es.

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

Ciò farà sì che filtroEquals restituisca false.

Avevo bisogno di una soluzione simile per l'invio di notifiche di sms da più numeri, , al fine di consentire alla notifica di avviare il visualizzatore di file sms con numeri diversi.

+0

funziona anche questo? –

0

Inserire l'ID attività e un timestamp nell'azione dell'intento. In questo modo, associ l'intento in sospeso all'ID attività e gli intenti saranno comunque diversi in termini di filtro.

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

Nel mio caso non ho avuto un buon modo per generare una chiave univoca per i miei intenti in attesa così quello che ho fatto è stato aggiungere dati personalizzati per l'intento generato.

Dopo aver iniziato a riempire l'attributo di dati, è necessario ricordare di aggiungere un parametro di dati al filtro intent sul manifest Android. Se non lo fai, non attiverà il tuo ricevitore personalizzato.

Esempi:

intento

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 ingresso

<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> 

In questo modo è anche possibile testare l'unicità nell'intento prima che venga aggiunto come intento in corso, che è utile se fai un test unitario

Problemi correlati