我正在开发适用于Android的QR阅读器应用。该应用程序的重点是使用手机摄像头读取QR码。如果用户不使用该应用程序,则相机会在一定时间后停止(为此使用Timer
),以防止消耗电池并振动手机,并显示一条吐司消息并指示用户按按钮以重新激活相机,然后继续其工作。
问题是,当第一次触发该事件时,一切都会按我的预期进行,但是如果第二次触发,该Toast将显示两次,依此类推,如果该事件触发了N个数字的时间。
此替代方法背后的逻辑是:
“恢复”摄像机功能的按钮逻辑:
btnEncenderCamara.Click += (sender, e) => {
camara.Start(lectorQR.Holder);
btnEncenderCamara.Enabled = false;
timerToDisableCamera.Interval = 6000;
timerToDisableCamera.Elapsed += new ElapsedEventHandler(timerElapsed);
timerToDisableCamera.Start();
};
和计时器的事件逻辑在这里:
protected void timerElapsed(object sender, ElapsedEventArgs e) {
try
{
timerToDisableCamera.Stop();
RunOnUiThread(() => {
Vibrator vibrator = (Vibrator)GetSystemService(Context.VibratorService);
vibrator.Vibrate(1000);
camara.Stop();
btnEncenderCamara.Enabled = true;
Toast.MakeText(this, "La cámara se ha detenido para ahorrar en cosumo de batería. Presione 'ENCENDER CÁMARA' para encender la cámara nuevamente", ToastLength.Short).Show();
});
}
catch (Exception ex)
{
throw;
}
}
一旦停止相机的事件被触发,我就需要找到避免Toast多次显示的方法。
答案 0 :(得分:1)
请注意,每次触发btnEncenderCamara.Click时,如何在btnEncenderCamara.Click事件中向timerToDisableCamera.Elapsed事件订阅新的委托。
因此,在以后每次调用btnEncenderCamara.Click时,都会多次调用timerElapsed方法。
解决此问题的一种方法是,在调用timerToDisableCamera.Stop()之后,在timerElapsed方法内退订您的委托,如下所示:
protected void timerElapsed(object sender, ElapsedEventArgs e) {
try
{
timerToDisableCamera.Stop();
timerToDisableCamera.Elapsed -= new ElapsedEventHandler(timerElapsed);
RunOnUiThread(() => {
Vibrator vibrator = (Vibrator)GetSystemService(Context.VibratorService);
vibrator.Vibrate(1000);
camara.Stop();
btnEncenderCamara.Enabled = true;
Toast.MakeText(this, "La cámara se ha detenido para ahorrar en cosumo de batería. Presione 'ENCENDER CÁMARA' para encender la cámara nuevamente", ToastLength.Short).Show();
});
}
catch (Exception ex)
{
throw;
}
}
或者,您可以重构代码以仅初始化一次计时器,这将使您的逻辑保持精益,如下所示:
// I'm assuming this method is an entry point for initialization in your Android activity.
void OnLoad()
{
// I'm assuming timerToDisableCamera already have an instance of Timer, otherwise you will get a NullReferenceException.
timerToDisableCamera.Interval = 6000;
timerToDisableCamera.Elapsed += new ElapsedEventHandler(timerElapsed);
// And also assuming that btnEncenderCamara is already an instance of Button.
btnEncenderCamara.Click += (sender, e) => {
camara.Start(lectorQR.Holder);
btnEncenderCamara.Enabled = false;
timerToDisableCamera.Start();
};
}
protected void timerElapsed(object sender, ElapsedEventArgs e)
{
try
{
timerToDisableCamera.Stop();
RunOnUiThread(() => {
Vibrator vibrator = (Vibrator)GetSystemService(Context.VibratorService);
vibrator.Vibrate(1000);
camara.Stop();
btnEncenderCamara.Enabled = true;
Toast.MakeText(this, "La cámara se ha detenido para ahorrar en cosumo de batería. Presione 'ENCENDER CÁMARA' para encender la cámara nuevamente", ToastLength.Short).Show();
});
}
catch (Exception ex)
{
throw;
}
}