Android Studio实现长按按钮每隔50ms向Arduino蓝牙发数据的方法
解决Android按住按钮定时通过蓝牙发送字符的问题
嘿,作为Android新手,你找的方向其实没错,但现有代码有两个致命问题——用错了触摸事件监听,而且阻塞了UI线程。我来一步步帮你完善,实现按住按钮期间每50毫秒发一次字符给Arduino的功能。
先说说你现有代码的核心问题
- 用
OnHoverListener不对:这个监听器是给鼠标悬浮操作设计的,Android触摸设备应该用OnTouchListener来处理按下、松开这类触摸事件。 while循环阻塞UI线程:在UI线程里写while(event.getAction() == MotionEvent.ACTION_DOWN)会直接卡死界面,因为Android的UI线程不能被长时间阻塞,否则会触发ANR(应用无响应)。
正确实现方案:OnTouchListener+Handler定时任务
我们的思路是:当按钮被按下(ACTION_DOWN)时,启动一个重复的定时任务,每隔50毫秒发送一次字符;当按钮被松开(ACTION_UP)或者触摸被中断(ACTION_CANCEL)时,立即停止这个任务。
下面是完整的代码示例:
// 定义Handler和Runnable,用来处理定时发送逻辑 private Handler sendHandler = new Handler(Looper.getMainLooper()); private Runnable sendRunnable = new Runnable() { @Override public void run() { // 发送字符给Arduino,注意:蓝牙IO操作不能在UI线程执行 sendData("d"); // 50毫秒后再次执行当前Runnable,实现循环发送 sendHandler.postDelayed(this, 50); } }; // 给按钮设置触摸监听器 base_destra.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 按钮被按下,启动定时发送任务 sendHandler.post(sendRunnable); return true; // 告诉系统我们处理了这个触摸事件 case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // 按钮被松开或触摸中断,停止定时发送任务 sendHandler.removeCallbacks(sendRunnable); return true; default: return false; } } }); // 蓝牙发送方法:必须在后台线程执行IO操作 private void sendData(String data) { // 假设你已经通过蓝牙连接获取到了有效的OutputStream对象(比如叫outputStream) if (outputStream != null) { new Thread(new Runnable() { @Override public void run() { try { outputStream.write(data.getBytes()); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); // 这里可以添加错误处理,比如提示用户蓝牙连接异常 } } }).start(); } }
关键注意事项
- 蓝牙操作必须在后台线程:蓝牙的
OutputStream.write()是IO操作,绝对不能放在UI线程里,否则会导致界面卡顿甚至ANR,所以上面的sendData方法专门开了子线程执行发送。 - 避免内存泄漏:在Activity/Fragment销毁时,记得移除Handler的回调,防止内存泄漏:
@Override protected void onDestroy() { super.onDestroy(); sendHandler.removeCallbacks(sendRunnable); } - 蓝牙连接前置准备:确保调用
sendData前,已经成功和Arduino建立蓝牙连接,并获取到有效的OutputStream对象(这部分需要你自己实现蓝牙配对、连接逻辑,比如通过BluetoothSocket获取输出流)。
这样修改后,就能完美实现“按住按钮期间每隔50毫秒发一次字符”的需求,而且不会阻塞UI线程,触摸事件处理也符合Android规范。
内容的提问来源于stack exchange,提问作者Gabriele Trevisan
相关产品推荐
相关产品推荐

