我在运行Android应用时遇到问题。 当我触地时,无法调用摇动监听器。 我的逻辑是“当我摇晃时发送信息并同时按下按钮。但似乎这对我的听众部分不起作用。 但android工作室无法告诉我错误或代码在哪里错误。
这是我的按钮代码。
shakeitBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(getBaseContext(), "Shake!", Toast.LENGTH_SHORT).show();
mShakeDetector = new ShakeDetector(new ShakeDetector.OnShakeListener() {
public void onShake() {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(300);
status = RELEASE_TO_SEND;
}
});
break;
case MotionEvent.ACTION_UP:
if (status == RELEASE_TO_CANCEL) {
Toast.makeText(getBaseContext(), "Shake canceled", Toast.LENGTH_SHORT).show();
} else {
if (status == RELEASE_TO_SEND) {
DatabaseReference childRoot = rootRoomName.push();
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", userName);
map.put("message", "I AM BUSY!!!".toString());
childRoot.updateChildren(map);
}
else{}
}
break;
case MotionEvent.ACTION_MOVE:
if (event.getY() < 0) {
status = RELEASE_TO_CANCEL;
} else {
}
break;
default:
break;
}
return true;
}
});
@Override
public void onResume() {
chat_room.super.onResume();
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
@Override
public void onPause() {
mSensorManager.unregisterListener(mShakeDetector);
chat_room.super.onPause();
}
这是我的共享检测器代码
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
public class ShakeDetector implements SensorEventListener {
// Minimum acceleration needed to count as a shake movement
private static final int MIN_SHAKE_ACCELERATION = 5;
// Minimum number of movements to register a shake
private static final int MIN_MOVEMENTS = 2;
// Maximum time (in milliseconds) for the whole shake to occur
private static final int MAX_SHAKE_DURATION = 500;
// Arrays to store gravity and linear acceleration values
private float[] mGravity = {0.0f, 0.0f, 0.0f};
private float[] mLinearAcceleration = {0.0f, 0.0f, 0.0f};
// Indexes for x, y, and z values
private static final int X = 0;
private static final int Y = 1;
private static final int Z = 2;
// OnShakeListener that will be notified when the shake is detected
private OnShakeListener mShakeListener;
// Start time for the shake detection
long startTime = 0;
// Counter for shake movements
int moveCount = 0;
// Constructor that sets the shake listener
public ShakeDetector(OnShakeListener shakeListener) {
mShakeListener = shakeListener;
}
@Override
public void onSensorChanged(SensorEvent event) {
// This method will be called when the accelerometer detects a change.
// Call a helper method that wraps code from the Android developer site
setCurrentAcceleration(event);
// Get the max linear acceleration in any direction
float maxLinearAcceleration = getMaxCurrentLinearAcceleration();
// Check if the acceleration is greater than our minimum threshold
if (maxLinearAcceleration > MIN_SHAKE_ACCELERATION) {
long now = System.currentTimeMillis();
// Set the startTime if it was reset to zero
if (startTime == 0) {
startTime = now;
}
long elapsedTime = now - startTime;
// Check if we're still in the shake window we defined
if (elapsedTime > MAX_SHAKE_DURATION) {
// Too much time has passed. Start over!
resetShakeDetection();
} else {
// Keep track of all the movements
moveCount++;
// Check if enough movements have been made to qualify as a shake
if (moveCount > MIN_MOVEMENTS) {
// It's a shake! Notify the listener.
mShakeListener.onShake();
// Reset for the next one!
resetShakeDetection();
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Intentionally blank
}
private void setCurrentAcceleration(SensorEvent event) {
/*
* BEGIN SECTION from Android developer site. This code accounts for
* gravity using a high-pass filter
*/
// alpha is calculated as t / (t + dT)
// with t, the low-pass filter's time-constant
// and dT, the event delivery rate
final float alpha = 0.8f;
// Gravity components of x, y, and z acceleration
mGravity[X] = alpha * mGravity[X] + (1 - alpha) * event.values[X];
mGravity[Y] = alpha * mGravity[Y] + (1 - alpha) * event.values[Y];
mGravity[Z] = alpha * mGravity[Z] + (1 - alpha) * event.values[Z];
// Linear acceleration along the x, y, and z axes (gravity effects removed)
mLinearAcceleration[X] = event.values[X] - mGravity[X];
mLinearAcceleration[Y] = event.values[Y] - mGravity[Y];
mLinearAcceleration[Z] = event.values[Z] - mGravity[Z];
/*
* END SECTION from Android developer site
*/
}
private float getMaxCurrentLinearAcceleration() {
// Start by setting the value to the x value
float maxLinearAcceleration = mLinearAcceleration[X];
// Check if the y value is greater
if (mLinearAcceleration[Y] > maxLinearAcceleration) {
maxLinearAcceleration = mLinearAcceleration[Y];
}
// Check if the z value is greater
if (mLinearAcceleration[Z] > maxLinearAcceleration) {
maxLinearAcceleration = mLinearAcceleration[Z];
}
// Return the greatest value
return maxLinearAcceleration;
}
private void resetShakeDetection() {
startTime = 0;
moveCount = 0;
}
// (I'd normally put this definition in it's own .java file)
public interface OnShakeListener {
public void onShake();
}
}
答案 0 :(得分:0)
正如你所说,如果你在onTouch()
bool vibrateOnShake = false;
之前启动ShakeDetector,我建议如下:
1)在您的活动/片段中创建一个参数:
mShakeDetector = new ShakeDetector(new ShakeDetector.OnShakeListener() {
public void onShake() {
if (vibrateOnShake) {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(300);
status = RELEASE_TO_SEND;
}
}
});
2)在onTouch()之外启动ShakeDetector:
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
vibrateOnShake = true;
...
break;
...
}
}
3)更新你的onTouch():
y = y++;