2011-12-22 1 views
5

У меня есть приложение таймера, и я хочу, чтобы вибрировать телефон, как только таймер закончит. В настоящий момент я могу воспроизводить звук до тех пор, пока не будет нажата кнопка OK, но он только вибрирует один раз. Как можно повторить вибрацию, пока пользователь не нажмет кнопку OK?Вибрация до закрытого окна сообщений Windows Phone 7

Это мой текущий код

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

UPDATE: Я попытался ответ Джо, который работает, если я не называю MessageBox.Show() Это, кажется, останавливаться на этом, пока ОК не будет нажата.

+0

вы хотите, чтобы непрерывно вибрирует, или пульс? – Joe

+0

@Joe Я хочу, чтобы он пульсировал – Chris

+6

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

ответ

2

VibrateController.Start(Timespan) выдаст ошибку, если передать значение больше 5 секунд, так что вам нужно сделать некоторые хитрости, чтобы сохранить это происходит. Создайте таймер и установите его для перезапуска вибрации. Например:

отредактировал

Глупый меня, я забыл, что оба Messagebox и DispatcherTimer будет работать на том же потоке. Messagebox заблокирует его. Попробуй это.

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

Так что я использую System.Threading.Timer вместо диспетчера. Это в основном то же самое, только немного меньше очевидного API. Вместо того, чтобы звонить Start() and Stop(), вы должны передать сумму задержки. Чтобы запустить его, передать в 0. Это будет продолжать идти через каждые 1,3 секунд, пока вы не вызовете Change() переходящими в Timeout.Infinite

Несколько вещей, чтобы отметить:

  • vibrate.Start(vibrateDuration) является только вызывается из клеща мероприятие. Это связано с тем, что таймер сразу начнет.
  • За предложение Mystere Man's, я добавил тайм-аут. вам нужно что-то подобное.
  • Вы могли бы хотеть, чтобы реорганизовать и очистить свой образец
+0

Я думаю, что MessageBox.Show() вмешивается в это.Если я удаляю время и вибрирует методы остановки, тогда его начало вибрировать непрерывно после нажатия кнопки OK. – Chris

+0

@ Крис, если вы удалите стопы() s из инструкции if? – Joe

+0

, если я удаляю стоп() s, телефон начинает вибрировать после нажатия кнопки OK – Chris

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