要求:确保仅在按钮保持至少1秒后才执行itemLookup
。当按钮被按住3秒钟时停止按钮事件,因此用于查找的记录将不包含不必要的数据。
MotionEvent.ACTION_CANCEL
之前调用了TableLayoutForIntercept
' onInterceptTouchEvent
MainActivity
OnTouchListener
按预期调用1}}事件。也许我不理解onInterceptTouchEvent
的目的?我已经查看过有关此事的其他帖子,但所有帖子都在处理滑动或拖动事件,而不是取消按下按钮。也许这无法完成?代码:仅显示MainActivity
的相关部分,以及完整的TableLayoutForIntercept
类,当然还有<com.company.myapplication.TableLayoutForIntercept></com.company.myapplication.TableLayoutForIntercept>
个标记围绕我的xml布局。
public class MainActivity extends Activity {
//...
DateTime recordingStartedTime;
DateTime recordingEndedTime;
boolean buttonHeldLongEnough = false;
PackageManager pm = getPackageManager();
boolean micPresent = pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE);
if (micPresent) {
recordBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View recordView, MotionEvent recordEvent) {
switch (recordEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
// Try to record audio
try {
recordingOff.setVisibility(View.INVISIBLE);
recordingOn.setVisibility(View.VISIBLE);
recordingStartedTime = DateTime.now();
constructPrepareStartRecording();
}
catch (Exception ex) {
Log.e(MainActivity.class.getSimpleName(), "An unknown error occurred.");
}
return true;
case MotionEvent.ACTION_UP:
recordingOff.setVisibility(View.VISIBLE);
recordingOn.setVisibility(View.INVISIBLE);
recordingEndedTime = DateTime.now();
Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime);
int secondsButtonHeld = seconds.getSeconds();
// Button must have been held at least 1 second before running itemLookup
if (secondsButtonHeld > 0 ) {
buttonHeldLongEnough = true;
}
else {
buttonHeldLongEnough = false;
}
// Need to release resources regardless
stopReleaseResetRecording();
if (buttonHeldLongEnough) {
itemLookup();
}
return true;
case MotionEvent.ACTION_CANCEL:
// I think this is the event I have to trigger to halt the button press
boolean codeHasHitCancel = true;
return codeHasHitCancel;
}
return false;
}
});
}
else {
toastTitle = "Unable To Record";
toastMessage = "Device microphone not found.";
toast = new GenericCustomToast();
toast.show(toastTitle, toastMessage, MainActivity.this);
}
//...
}
public class TableLayoutForIntercept extends TableLayout {
public TableLayoutForIntercept (Context context) {
super(context);
}
public TableLayoutForIntercept (Context context, AttributeSet attrs) {
super(context, attrs);
}
private CancelPressTask cancelPressTask = null;
private boolean stopTouchEvent = false;
@Override
public boolean onInterceptTouchEvent (MotionEvent event) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
stopTouchEvent = false;
cancelPressTask = new CancelPressTask();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
cancelPressTask.resetCancelPressTimer();
cancelPressTask.stopCancelPressTimer();
return stopTouchEvent;
}
return super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent (MotionEvent event) {
if (!stopTouchEvent) {
return super.onTouchEvent(event);
}
return true;
}
private class CancelPressTask {
public final long CANCEL_PRESS_TIMEOUT = 3000; // 3 seconds
private Handler cancelPressHandler = new Handler(){
public void handleMessage(Message msg) {
}
};
private Runnable cancelPressCallback = new Runnable() {
@Override
public void run() {
stopTouchEvent = true;
}
};
public void resetCancelPressTimer(){
cancelPressHandler.removeCallbacks(cancelPressCallback);
cancelPressHandler.postDelayed(cancelPressCallback, CANCEL_PRESS_TIMEOUT);
}
public void stopCancelPressTimer(){
cancelPressHandler.removeCallbacks(cancelPressCallback);
}
}
}
答案 0 :(得分:0)
我想出了另一种解决方法。我决定窃取而不是试图触发一个事件!以下代码将停止录制,然后在3秒后完成项目查找,无论用户尝试按住该按钮多长时间。唯一的问题是对于太短(不到1秒)的录音,它仍然需要整整3秒才能通过Toast消息通知用户。但我愿意接受这一点。
public class Main Activity extends Activity {
DateTime recordingStartedTime;
DateTime recordingEndedTime = null;
boolean buttonHeldLongEnough = false;
LimitRecordingTask limitRecordingTask;
PackageManager pm = getPackageManager();
boolean micPresent = pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE);
if (micPresent) {
recordBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View recordView, MotionEvent recordEvent) {
limitRecordingTask = new LimitRecordingTask();
switch (recordEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
// Try to record audio
try {
recordBtn.setBackgroundColor(Color.DKGRAY);
recordingOff.setVisibility(View.INVISIBLE);
recordingOn.setVisibility(View.VISIBLE);
recordingStartedTime = DateTime.now();
constructPrepareStartRecording();
limitRecordingTask.resetRecordingTimer();
}
catch (Exception ex) {
Log.e(MainActivity.class.getSimpleName(), "An unknown error occurred.");
limitRecordingTask.stopRecordingTimer();
}
return true;
case MotionEvent.ACTION_UP:
// After 3 seconds limitRecordingTask will 'steal' this event
recordBtn.setBackgroundResource(R.drawable.custom_button);
recordingOff.setVisibility(View.VISIBLE);
recordingOn.setVisibility(View.INVISIBLE);
recordingEndedTime = DateTime.now();
Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime);
int secondsButtonHeld = Math.abs(seconds.getSeconds());
if (secondsButtonHeld > 0 ) {
buttonHeldLongEnough = true;
}
else {
buttonHeldLongEnough = false;
}
return true;
}
return false;
}
});
}
else {
toastTitle = "Unable To Record";
toastMessage = "Device microphone not found.";
toast = new GenericCustomToast();
toast.show(toastTitle, toastMessage, MainActivity.this);
}
private class LimitRecordingTask {
public final long RECORDING_TIMEOUT = 3000; // 3 seconds
private Handler limitRecordingHandler = new Handler(){
public void handleMessage(Message msg) {
}
};
private Runnable limitRecordingCallback = new Runnable() {
@Override
public void run() {
// 'Stolen' MotionEvent.ACTION_UP
recordBtn.setBackgroundResource(R.drawable.custom_button);
recordingOff.setVisibility(View.VISIBLE);
recordingOn.setVisibility(View.INVISIBLE);
if (recordingEndedTime == null) {
recordingEndedTime = DateTime.now();
}
Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime);
int secondsButtonHeld = Math.abs(seconds.getSeconds());
if (secondsButtonHeld > 0 ) {
buttonHeldLongEnough = true;
}
else {
buttonHeldLongEnough = false;
}
limitRecordingTask.stopRecordingTimer();
stopReleaseResetRecording();
itemLookup();
}
};
public void resetRecordingTimer(){
limitRecordingHandler.removeCallbacks(limitRecordingCallback);
limitRecordingHandler.postDelayed(limitRecordingCallback, RECORDING_TIMEOUT);
}
public void stopRecordingTimer(){
limitRecordingHandler.removeCallbacks(limitRecordingCallback);
}
}
}