Вибрация до закрытия окна сообщения Windows Phone 7 - PullRequest
5 голосов
/ 22 декабря 2011

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

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

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.

Ответы [ 2 ]

2 голосов
/ 22 декабря 2011

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

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

Несколько замечаний:

  • vibrate.Start(vibrateDuration) - это только , вызванный из события тика. Это потому, что Таймер немедленно сработает.
  • За Мистер Человек предложение, я добавил тайм-аут. вы захотите что-то подобное.
  • Возможно, вы захотите провести рефакторинг и очистить мой образец
0 голосов
/ 22 декабря 2011
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));
           }
        }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...