5

私は、ユーザーが監視するいくつかの株を選択でき、事前定義されたアラート条件が一致した場合にアラートを受け取ることができるAndroidアプリケーションを作成しています。在庫データは、カスタムParcelableクラス「アラート」の5つのオブジェクトに保存されます(在庫と条件ごとに1つのオブジェクト)。定期的なデータ更新は、AlarmManagerによって開始されたサービスを介して行われます。アラートオブジェクトは、AlarmManagerのPendingIntentに配置されるIntentに配置することでサービスに渡されます。

    Intent intent = new Intent(this, UpdateService.class);
    Bundle b = new Bundle();
    saveAlertsToBundle(b);      
    intent.putExtras(b);
    intent.setData(Uri.parse("updateManager"));
    PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0);

    // 1min intervall
    long intervall = DateUtils.MINUTE_IN_MILLIS * 1;
    // time of first start
    long firstStartDelay = DateUtils.SECOND_IN_MILLIS * 30;
    long firstStart = System.currentTimeMillis() + firstStartDelay;

    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    // kill running
    am.cancel(pendIntent);
    //start new
    am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent);

私の問題は:

サービスに渡されるアラートのオブジェクトが1つしかないときに初めてサービスを開始するときは、すべてが正常に機能します。アラートオブジェクトがさらに存在するようになるとすぐに、それらもサービスに渡す必要がありますが、これは上記のコードでは機能しません。サービスは、追加のアラートオブジェクトで更新されたインテントを受信しませんが、アラートオブジェクトが1つだけの最初のインテントのみを受信します。上記のコードは、追加のアラートオブジェクトを保持するインテントを正しく作成しますが、サービスに到達することはありません。

だから私の質問は、更新されたインテントをすでに実行中のAlarmManagerに渡す方法です。

すでにAlarmManager(//実行中のコメントを強制終了する行)を停止して再起動しようとしましたが、これは機能しません。おそらく、彼が作成されたときと同じアラートオブジェクトを保持していないという意図のためですか?インテントのデータ部分にURIを設定してこれを修正しようとしましたが、これも役に立ちませんでした。

手伝ってくれてありがとう。

4

1 に答える 1

2

あなたの問題は働き方PendingIntentです。システムはのプールを管理しますPengingIntent。あなたのコードがそうするとき:

PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0);

これにより、システムPendingIntentは渡されたパラメータ(この場合は。)に一致するを検索しますIntent。ただし、を使用する一致アルゴリズムは、のPendingIntent特定のフィールドのみを比較してIntent、それが探しているものであるかどうかを判断します。特に、エクストラを比較しません。つまり、最初のを作成した後PendingIntent、への呼び出しPendingIntent.getService()は常にPendingIntentプールから同じものを返します(新しいものは作成しません。これは必要なものです)。

呼び出すたびPendingIntent.getService()に新しいものを作成するために呼び出しを行うには、次のように、呼び出しに渡すパラメーターを一意にするようにしてください。PendingIntent

int requestCode = (int) System.currentTimeMillis(); // Create unique request code
PendingIntent pendIntent = PendingIntent.getService(this, requestCode, intent, 0);

requestCodeの呼び出しごとに異なるため、PendingIntent.getService()これで問題が解決するはずです。

以下のOPのコメントに基づいて編集

既存のアラームをキャンセルして、新しいデータで新しいアラームを作成したいとします。PendingIntentその場合、プールに1つだけ入れたいので、一意の識別子を使用する必要はありません。ただし、そのためのデータを変更する必要があります。これを試して:

// Create a PendingIntent (or update the existing PendingIntent with new values
PendingIntent pendIntent = PendingIntent.getService(this, 0, intent,
                      PendingIntent.FLAG_UPDATE_CURRENT);

AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// cancel any pending alarms
am.cancel(pendIntent);
//start new
am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent);
于 2012-09-24T19:33:50.757 に答える