5

タイマーアプリがあり、タイマーが終了したら電話を振動させたいです。現在、OK ボタンを押すまで音を鳴らすことができますが、振動は 1 回だけです。ユーザーがOKボタンを押すまで振動を繰り返すにはどうすればよいですか?

これは私の現在のコードです

SoundEffectInstance alarmSound = PlaySound(@"Alarms/"+alarmSoundString);

VibrateController vibrate = VibrateController.Default;

vibrate.Start(new TimeSpan(0,0,0,0,1000));

MessageBoxResult alarmBox = MessageBox.Show("Press OK to stop alarm", "Timer Finished", MessageBoxButton.OK);

if (alarmBox == MessageBoxResult.OK)
{
    alarmSound.Stop();
    vibrate.Stop();
}

更新: ジョーの応答を試してみました。これは、呼び出さなくても機能しますMessageBox.Show()。OK が押されるまで、この時点で停止するようです。

4

2 に答える 2

2

VibrateController.Start(Timespan)5 秒を超える値を渡すとエラーがスローされるため、それを継続するにはいくつかのトリックを行う必要があります。タイマーを作成し、振動を再開するように設定します。例えば:

編集済み

愚かなことに、Messagebox と DispatcherTimer の両方が同じスレッドで実行されることを忘れていました。メッセージボックスはそれをブロックします。これを試して。

public partial class MainPage : PhoneApplicationPage
{
    TimeSpan vibrateDuration = new TimeSpan(0, 0, 0, 0, 1000);
    System.Threading.Timer timer;
    VibrateController vibrate = VibrateController.Default;
    int timerInterval = 1300;
    SoundEffectInstance alarmSound = PlaySound(@"Alarms/"+alarmSoundString);
    TimeSpan alramDuration; //used to make it timeout after a while

    public MainPage()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        timer = new Timer(new TimerCallback(timer_Tick), null, 0, timerInterval);
        alramDuration = TimeSpan.FromSeconds(0);
        alarmSound.Play();
        MessageBoxResult alarmBox = MessageBox.Show("Press OK to stop alarm", "Timer Finished", MessageBoxButton.OK);

        if (alarmBox == MessageBoxResult.OK)
        {
            StopAll();
        }
    }

    void timer_Tick(object sender)
    {
        //keep track of how long it has been running
        //stop if it has gone too long
        //otheriwse restart

        alramDuration = alramDuration.Add(TimeSpan.FromMilliseconds(timerInterval)); 
        if (alramDuration.TotalMinutes > 1)
            StopAll();
        else
            vibrate.Start(vibrateDuration);
    }

    void StopAll()
    {
        timer.Change(Timeout.Infinite, Timeout.Infinite);
        vibrate.Stop();
        alarmSound.Stop();
    }
}

そのため、Dispatcher の代わりにSystem.Threading.Timerを使用しています。基本的には同じですが、明白な API が少し劣っているだけです。呼び出す代わりにStart() and Stop()、遅延量を渡す必要があります。Change()開始するには、0 を渡します。Timeout.Infinite を渡すまで、1.3 秒ごとにオフになり続けます。

注意すべき点がいくつかあります。

  • vibrate.Start(vibrateDuration)tick イベントからのみ呼び出されます。これは、タイマーがすぐに開始されるためです。
  • Mystere Man の提案に従って、タイムアウトを追加しました。あなたはこのようなものが欲しくなるでしょう。
  • リファクタリングしてサンプルをクリーンアップすることをお勧めします
于 2011-12-22T17:46:10.733 に答える
0
SoundEffectInstance alarmSound = PlaySound(@"Alarms/"+alarmSoundString);

VibrateController vibrate = VibrateController.Default;

var vibrationLength = 1000;
var startTime = DateTime.Now;
vibrate.Start(new TimeSpan(0,0,0,0,vibrationLength));

MessageBoxResult alarmBox = MessageBox.Show("Press OK to stop alarm", "Timer Finished", MessageBoxButton.OK);
var ok = false;

While (!ok){
  if (alarmBox == MessageBoxResult.OK)
  {
    ok = true;
  }
  else{
     if(startTime.AddMilliseconds(vibrationLength * 1.2) < DateTime.Now)
     {
        startTime = DateTimne.Now;
        vibrate.Start(new TimeSpan(0,0,0,0,vibrationLength));
     }
  }
}

alarmSound.Stop();
vibrate.Stop();

だいたい

私は Windows Phone 用のコードを書いていないので、電話が応答しなくなる可能性があります。しかし、一般的なアイデアは、ユーザーが問題なくヒットしたかどうかをチェックし続け、そうでない場合は、最後のバイブレーションが開始されてから新しいバイブレーションを開始するのに十分な時間が経過したかどうかを確認することです。

パルスにしたい場合は、 AddMilliseconds を使用して、必要なパルス長よりも長い長さを追加することをお勧めします。

代わりにタイマーを使用する

クラスのふりをすると、次のようになります

public class buzzz
{

   MessageBoxResult alarmBox;
   DispatchTimer alarmTimer = new DispatchTimer();
   var vibrationLength = 1000.0;
   var timerIncrease = 1.2;
   VibrateController vibrate = VibrateController.Default;

   public buzz()
   {
      alarmTimer.Interval = TimeSpan.FromMillseconds(vibrationLegnth * timerIncrease);
      alarmTimer.Tick += alarmTimer_Tick
   }
   public void startBuzz()
   {
       SoundEffectInstance alarmSound = PlaySound(@"Alarms/"+alarmSoundString);
       vibrate.Start(new TimeSpan(0,0,0,0,vibrationLength));
       alarmTimer.Start();
       alarmBox = MessageBox.Show("Press OK to stop alarm", "Timer Finished", MessageBoxButton.OK);
    }

    void alarmTimer_Tick(object sender, EventArgs e)
        {
           if(alarmBox == MessageBoxResult.OK)
           {
              alarmTimer.Stop();
              vibrate.Stop();
           }
           else
           {
               vibrate.Start(new TimeSpan(0,0,0,0,vibrationLength));
           }
        }
}
于 2011-12-22T17:43:06.667 に答える