下面是-http://pi4j.com/example/listener.html(收听GPIO)。我想知道是否有一种方法可以在特定的时间范围内禁止事件被触发。例如,我有一个运动检测器,并希望对其进行配置,以便一旦检测到运动,它就会打开一盏灯。但是,如果在接下来的15分钟内(在灯打开后)再次检测到运动,则应丢弃这些事件(运动)。
public class ListenGPIO {
public static void main(String args[]) throws InterruptedException {
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN);
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
}
});
System.out.println(" ... complete the GPIO #02 circuit and see the listener feedback here in the console.");
for (;;) {
Thread.sleep(500);
}
}
}
我尝试在handleGpioPinDigitalStateChangeEvent中添加Thread.sleep,但这会使事件线程进入睡眠状态,但一旦线程醒来,它就会开始处理以前的事件,即事件存储在某种队列中,并进行我希望避免的处理。
您可以忽略事件一段时间,而不是睡觉
long waitUntilTime = -1L;
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
long time = System.currentTimeMillis();
if (time >= waitUntilTime) {
waitUntilTime = time + TIME_TO_IGNORE_EVENTS;
processEvent(event);
}
}
有三种方法可以处理,两种有定时器,一种没有,这也取决于您使用的API:
1) 在上次激发事件时添加要存储的变量。如果发生新事件,请比较时间。如果15分钟已经过去,则处理该事件,否则忽略它
public class ListenGPIO {
private long lastFiredMillis = -1;
public static void main(String args[]) throws InterruptedException {
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN);
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
if(lastFiredMillis == -1 || (System.currentTimeMillis() - lastFiredMillis) > 15 * 60 * 1000) {
lastFiredMillis = System.currentTimeMillis();
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
}
}
});
}}
2) 删除监听器,15分钟后重新添加当然,只有当您的API有一个方法来删除侦听器时,这才有效
3) 保留侦听器但忽略事件,可以设置一个全局布尔标志来处理此问题。
public class ListenGPIO {
private boolean mHandleEvents = true;
public static void main(String args[]) throws InterruptedException {
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN);
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
if(mHandleEvents) {
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
mHandleEvents = false; //prevent
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
mHandleEvents = true
}
}, 15 * 60 * 1000);
}
}
});
}}