4

こんにちは、ご協力ありがとうございます。

AlarmManager を使用して、次の数週間、数か月間、1 日 1 つのアラームを設定するアプリケーションがあります...

  • アクティビティを開始するために、曜日ごとに 1 つのアラームを設定しました

  • しばらくしてからアクティビティを停止するための、曜日ごとに 1 つのアラーム

次の行で説明しようとする次の問題があります。

今日は水曜日です、

アプリケーションを開き、月曜日、火曜日、水曜日、木曜日、金曜日、土曜日、日曜日にアラームを設定します...アラームを設定するとすぐに:

MON と TUE のすべてのアラームがすぐにオフになり、アクティビティの 4 つのインスタンスが発生します !!!!

どうすればこれを回避できますか???

私のコードの一部を見てください:

        // SET THE ALARM FOR STARTING THE ACTIVITY 
        Intent smon = new Intent(ctxt, VideoActivty.class);
        smon.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent psmon = PendingIntent.getActivity(ctxt, 0, smon, 0);

        Calendar calSet = Calendar.getInstance();
        calSet.set(Calendar.DAY_OF_WEEK, 2);
        calSet.set(Calendar.HOUR_OF_DAY, hsmon);
        calSet.set(Calendar.MINUTE, msmon);
        calSet.set(Calendar.SECOND, 0);
        calSet.set(Calendar.MILLISECOND, 0);

        mgr.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
                7 * 24 * 60 * 60 * 1000, psmon);

        // SET THE ALARM FOR KILLING THE ACTIVITY 
        Intent fmon = new Intent(ctxt, VideoActivty.class);
        fmon.putExtra("finish", true);
        PendingIntent pfmon = PendingIntent.getActivity(ctxt, 0, fmon, 0);

        calSet.set(Calendar.DAY_OF_WEEK, 2);
        calSet.set(Calendar.HOUR_OF_DAY, hfmon);
        calSet.set(Calendar.MINUTE, mfmon);
        calSet.set(Calendar.SECOND, 0);
        calSet.set(Calendar.MILLISECOND, 0);

        mgr.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
                7 * 24 * 60 * 60 * 1000, pfmon);

これはアクティビティです:

public class VideoActivty extends Activity {
private VideoView video;
private MediaController ctlr;
private PowerManager.WakeLock wl;
private KeyguardLock keyguard;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //
    PowerManager pm = (PowerManager) this
            .getSystemService(this.POWER_SERVICE);
    wl = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK, "");
    wl.acquire();

    KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    keyguard = km.newKeyguardLock("MyApp");
    keyguard.disableKeyguard();

    getWindow().setFormat(PixelFormat.TRANSLUCENT);
    VideoView videoHolder = new VideoView(this);
    //if you want the controls to appear
    videoHolder.setMediaController(new MediaController(this));
    Uri video = Uri.parse("android.resource://" + getPackageName() + "/" 
    + R.raw.ingress); //do not add any extension
    //if your file is named sherif.mp4 and placed in /raw
    //use R.raw.sherif
    videoHolder.setVideoURI(video);
    setContentView(videoHolder);

    videoHolder.start();
    videoHolder.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {

                        mp.start();
        }
    });
}


@Override
protected void onNewIntent (Intent i){


  if( i.getBooleanExtra("finish",false) ){
      wl.release();
      keyguard.reenableKeyguard();
      finish();
  }
}


}
4

4 に答える 4

5

set(...)およびsetRepeating(...)メソッドに関するAlarmManagerの API ページの状態:

「指定されたトリガー時間が過去にある場合、アラームはすぐにトリガーされ、トリガー時間が繰り返し間隔に対してどれだけ過去にあるかに応じてアラームカウントが行われます。」

したがって、たとえば水曜日にいる場合、AlarmManager は次のイベントを発生させます: 日曜日、月曜日、火曜日、および (おそらく) 水曜日。実際には、それらすべてに対して 1 つだけ起動します。

これが私がこれを回避する方法です。それが最善の方法かどうかはわかりませんが、スムーズに動作します。

AlarmManagerを起動したい曜日、時間、分を次の変数に保存するます

final int myAlarmDayOfTheWeek = ...;
final int myAlarmHour = ...;
final int myAlarmMinute = ...;

もちろん、ここではCalendar クラスと同じ規則で曜日を保存すると仮定しています。

日曜日 = Calendar.SUNDAY = 1

月曜日 = Calendar.MONDAY = 2

... ... ...

土曜日 = Calendar.SATURDAY = 7

それで:

Calendar timestamp = Calendar.getInstance();

//Check whether the day of the week was earlier in the week:
if( myAlarmDayOfTheWeek > timestamp.get(Calendar.DAY_OF_WEEK) ) {
    //Set the day of the AlarmManager:
    time.add(Calendar.DAY_OF_YEAR, (myAlarmDayOfTheWeek - timestamp.get(Calendar.DAY_OF_WEEK)));
}
else {
    if( myAlarmDayOfTheWeek < timestamp.get(Calendar.DAY_OF_WEEK) ) {
        //Set the day of the AlarmManager:
        timestamp.add(Calendar.DAY_OF_YEAR, (7 - (timestamp.get(Calendar.DAY_OF_WEEK) - myAlarmDayOfTheWeek)));
    }
    else {  // myAlarmDayOfTheWeek == time.get(Calendar.DAY_OF_WEEK)
        //Check whether the time has already gone:
        if ( (myAlarmHour < timestamp.get(Calendar.HOUR_OF_DAY)) || ((myAlarmHour == timestamp.get(Calendar.HOUR_OF_DAY)) && (myAlarmMinute < timestamp.get(Calendar.MINUTE))) ) {
            //Set the day of the AlarmManager:
            timestamp.add(Calendar.DAY_OF_YEAR, 7);
        }
    }
}

//Set the time of the AlarmManager:
timestamp.set(Calendar.HOUR_OF_DAY, myAlarmHour);
timestamp.set(Calendar.MINUTE, myAlarmMinute);
timestamp.set(Calendar.SECOND, 0);

Calendar.add(...)Calendar.DAY_OF_YEARを使用することにより、月の変更を処理する必要さえないことに注意してください...

最初の条件 (つまり、myAlarmDayOfTheWeek > timestamp.get(Calendar.DAY_OF_WEEK)) の場合は、Calendar.set(...)をフィールドとしてCalendar.DAY_OF_WEEK 、値としてmyAlarmDayOfTheWeekとともに使用することもできます。

あとは、AlarmManager をセットアップするだけです。例えば:

final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timestamp.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, myAlarmPendingIntent);

また、毎回日間隔 (つまり 24 * 60 * 60 * 1000) を計算することは避けてください。代わりにAlarmManager.INTERVAL_DAY (または最大で86400000 ) を使用してください。

于 2014-01-08T15:28:01.863 に答える
4

ここに解決策はありますか?私はまだ解決策を探しています.私のコードは以下のとおりです..

calendar.set(Calendar.DAY_OF_WEEK,getweekday(obj));
    calendar.set(Calendar.HOUR_OF_DAY,timepicker.getCurrentHour());
    calendar.set(Calendar.MINUTE, timepicker.getCurrentMinute());
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    if(calendar.before(cal_now)){//if its in the past increment
        calendar.add(Calendar.DATE,1);
    }

PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(),_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
    am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY * 7, sender);
于 2013-07-11T14:54:14.413 に答える