2017-04-04 56 views
0

我在運行我的android應用程序時出現問題。 當我觸摸時無法調用震動偵聽器。 我的邏輯是「當我晃動時發送消息並同時觸碰按鈕,但似乎無法爲我的聽衆部分工作 但是android studio不能告訴我錯誤或代碼錯誤在哪裏爲什麼我不能在ontouch事件中使用shake listener?

這裏是我的按鈕代碼

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

是否沒有onTouch()的ShakeDetector工作? –

+0

它可以工作。我試圖把按鈕上的搖動部分放出來,它可以發出消息。但是,當我將代碼放回按鈕部分時,它不起作用。 –

回答

0

正如你說的,如果你的onTouch()我建議以下之前啓動它的ShakeDetector作品:

1)在活動/片段創建參數:

bool vibrateOnShake = false; 

2)INIT您ShakeDetector的onTouch()以外:

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; 
     } 
    } 
}); 

3)更新您onTouch():

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    int action = event.getAction(); 

    switch (action) { 
     case MotionEvent.ACTION_DOWN: 
      vibrateOnShake = true; 
      ... 
      break; 
     ... 
    } 
} 
相關問題