2011-12-22 7 views
5

Ho un'app timer e voglio vibrare il telefono una volta che il timer è finito. Attualmente suono un suono finché non viene premuto il pulsante OK, ma vibra solo una volta. Come si può ripetere la vibrazione fino a quando l'utente preme il pulsante OK?Vibrazione fino a casella messaggio chiusa Windows Phone 7

Questo è il mio codice corrente

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: Ho provato la risposta di Joe, che funziona se non chiamo MessageBox.Show() Sembra di fermarsi a questo punto finché non si preme OK.

+0

si desidera vibrare in modo continuo, o impulsi? – Joe

+0

@Joe Voglio farlo pulsare – Chris

+6

È necessario assicurarsi di scadere dopo un periodo di tempo, altrimenti si rischia di scaricare la batteria per qualcuno che ha lasciato il telefono in un'altra stanza. –

risposta

2

VibrateController.Start(Timespan) genera un errore se si passa un valore superiore a 5 secondi in, quindi è necessario fare un po 'inganno per mantenere sta andando. Crea un timer e impostalo per riavviare la vibrazione. Per esempio:

modificati

Sciocco me, ho dimenticato che sia Messagebox e DispatcherTimer verrà eseguito sullo stesso thread. Il Messagebox lo bloccherà. Prova questo.

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

Quindi sto utilizzando un System.Threading.Timer anziché il Dispatcher. È principalmente la stessa, solo un po 'meno di un'API ovvia. Invece di chiamare Start() and Stop() devi passare un importo in ritardo. Per avviarlo, passano in 0. Manterrà andando fuori ogni 1,3 secondi fino a quando si chiama Change() passando Timeout.Infinite

Un paio di cose da notare:

  • vibrate.Start(vibrateDuration) è solo chiamato dalla zecca evento. Questo perché il Timer inizierà immediatamente.
  • Per Mystere Man's suggerimento, ho aggiunto un timeout. vorrete qualcosa di simile.
  • Si potrebbe desiderare di refactoring, e ripulire il mio campione
+0

Penso che MessageBox.Show() interferisca con questo.Se rimuovo il tempo e vibra i metodi di arresto, inizia a vibrare continuamente dopo aver premuto il pulsante OK – Chris

+0

@Chris se si rimuovono gli stop() s dall'istruzione if? – Joe

+0

se rimuovo lo stop() s il telefono inizia a vibrare dopo aver premuto il pulsante 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(); 

Circa

non scrivo codice per Windows Phone in modo da questo può causare il telefono per non rispondere. Ma l'Idea generale continua a controllare se l'utente ha colpito bene e, in caso contrario, se ha avuto abbastanza tempo da quando l'ultima vibrazione ha iniziato a iniziarne una nuova.

Se si desidera eseguire l'impulso, suggerirei di utilizzare AddMilliseconds e aggiungere una lunghezza maggiore della durata dell'impulso desiderata.

Utilizzando un timer invece

si finge classe assomiglia a questo

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