2011-12-22 18 views
5

Mam aplikację zegara i chcę wibrować telefon po upływie czasu. Mogę obecnie odtwarzać dźwięk do momentu naciśnięcia przycisku OK, ale wibruje on tylko raz. Jak powtórzyć wibracje, dopóki użytkownik nie naciśnie przycisku OK?Wibracja do czasu zamknięcia okna komunikatu Windows Phone 7

To jest mój aktualny kod

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: Próbowałem odpowiedź Joe, który działa, jeśli nie nazwać MessageBox.Show() Wydaje się zatrzymać w tym momencie aż naciśnięciu przycisku OK.

+0

chcesz go wibrować ciągły lub impulsowy? – Joe

+0

@Joe Chcę, żeby zadzwonił – Chris

+6

Powinieneś się upewnić, że upłynął czas po jakimś czasie, w przeciwnym razie możesz ryzykować wyczerpanie baterii dla kogoś, kto zostawił swój telefon w innym pokoju. –

Odpowiedz

2

VibrateController.Start(Timespan) wygeneruje błąd, jeśli przechodzą na wartość większą niż 5 sekund, więc trzeba zrobić kilka sztuczek, aby utrzymać idzie. Utwórz zegar i ustaw go, aby wznowił wibracje. Na przykład:

edytowany

Silly me, zapomniałem, że zarówno Messagebox i DispatcherTimer będzie działać na tym samym wątku. The Messagebox to zablokuje. Spróbuj tego.

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

Używam więc System.Threading.Timer zamiast Dispatchera. Jest to głównie to samo, tylko trochę mniej oczywistego API. Zamiast dzwonić pod numer Start() and Stop() musisz przekazać kwotę opóźnienia. Aby go uruchomić, przechodzą w 0. Będzie ona zachować schodzili się co 1,3 sekundy, aż zadzwonisz Change() przekazując Timeout.Infinite

kilka rzeczy do uwaga:

  • vibrate.Start(vibrateDuration) jest tylko nazywany od kleszczy zdarzenie. To dlatego, że Timer natychmiast się uruchomi.
  • Zgodnie z sugestią na temat , dodano limit czasu. będziesz chciał czegoś takiego.
  • Możecie chcą byłaby i oczyścić moją próbkę
+0

Myślę, że MessageBox.Show() ingeruje w to.Jeśli usunę metody czasu i wibracji zatrzymania, to jego początek będzie wibrująca w sposób ciągły po naciśnięciu przycisku OK – Chris

+0

@Chris, jeśli usuniesz przystanki() s z instrukcji if? – Joe

+0

po usunięciu stopera() s telefon zacznie wibrować po naciśnięciu przycisku 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(); 

grubsza

Nie piszę kod dla Windows Phone, więc to może spowodować, że telefon przestanie odpowiadać. Ale ogólną ideą jest sprawdzanie, czy użytkownik trafił w porządku, a jeśli nie, to wystarczy czasu, zanim zaczęły się nowe wibracje.

Jeśli chcesz impulsować, sugerowałbym użycie AddMilliseconds i dodanie długości większej niż długość impulsu.

Korzystanie czasomierza zamiast

udaje ci klasy wygląda następująco

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)); 
      } 
     } 
} 
Powiązane problemy