我正在尝试制作它,以便我摇动它时我的应用会发出声音。我认为我的摇动代码有效,但我遇到了媒体播放器的问题。我跟着peceps' answer for shake我使用了Chris' final answer for sound.显然我没有把它变成onClick而是onShake。
这是我的活动代码。 (我得到的唯一错误就是mp)
package com.grifball.info;
import com.grifball.info.ShakeDetector.OnShakeListener;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Bundle;
public class HammerActivity extends Activity {
private ShakeDetector mShakeDetector;
private SensorManager mSensorManager;
// Declare the MediaPlayer object
private MediaPlayer mMediaPlayer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hammer_page);
// ShakeDetector initialization
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mShakeDetector = new ShakeDetector();
mShakeDetector.setOnShakeListener(new ShakeDetector.OnShakeListener() {
public void onShake() {
// Initialize media player
mMediaPlayer = MediaPlayer.create(HammerActivity.this, R.raw.hammer);
// Add OnCompletionListener to release the
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mMediaPlayer.release();
}
});
mMediaPlayer.start();
});
};
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mShakeDetector,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause() {
mSensorManager.unregisterListener(mShakeDetector);
super.onStop();
}}
这是我的ShakeDetector代码。
package com.grifball.info;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
/**
* Listener that detects shake gesture.
*/
public class ShakeDetector implements SensorEventListener {
/** Minimum movement force to consider. */
private static final int MIN_FORCE = 10;
/**
* Minimum times in a shake gesture that the direction of movement needs to
* change.
*/
private static final int MIN_DIRECTION_CHANGE = 3;
/** Maximum pause between movements. */
private static final int MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE = 200;
/** Maximum allowed time for shake gesture. */
private static final int MAX_TOTAL_DURATION_OF_SHAKE = 400;
/** Time when the gesture started. */
private long mFirstDirectionChangeTime = 0;
/** Time when the last movement started. */
private long mLastDirectionChangeTime;
/** How many movements are considered so far. */
private int mDirectionChangeCount = 0;
/** The last x position. */
private float lastX = 0;
/** The last y position. */
private float lastY = 0;
/** The last z position. */
private float lastZ = 0;
/** OnShakeListener that is called when shake is detected. */
private OnShakeListener mShakeListener;
/**
* Interface for shake gesture.
*/
public interface OnShakeListener {
/**
* Called when shake gesture is detected.
*/
void onShake();
}
public void setOnShakeListener(OnShakeListener listener) {
mShakeListener = listener;
}
@Override
public void onSensorChanged(SensorEvent se) {
// get sensor data
float x = se.values[SensorManager.DATA_X];
float y = se.values[SensorManager.DATA_Y];
float z = se.values[SensorManager.DATA_Z];
// calculate movement
float totalMovement = Math.abs(x + y + z - lastX - lastY - lastZ);
if (totalMovement > MIN_FORCE) {
// get time
long now = System.currentTimeMillis();
// store first movement time
if (mFirstDirectionChangeTime == 0) {
mFirstDirectionChangeTime = now;
mLastDirectionChangeTime = now;
}
// check if the last movement was not long ago
long lastChangeWasAgo = now - mLastDirectionChangeTime;
if (lastChangeWasAgo < MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE) {
// store movement data
mLastDirectionChangeTime = now;
mDirectionChangeCount++;
// store last sensor data
lastX = x;
lastY = y;
lastZ = z;
// check how many movements are so far
if (mDirectionChangeCount >= MIN_DIRECTION_CHANGE) {
// check total duration
long totalDuration = now - mFirstDirectionChangeTime;
if (totalDuration < MAX_TOTAL_DURATION_OF_SHAKE) {
mShakeListener.onShake();
resetShakeParameters();
}
}
} else {
resetShakeParameters();
}
}
}
/**
* Resets the shake parameters to their default values.
*/
private void resetShakeParameters() {
mFirstDirectionChangeTime = 0;
mDirectionChangeCount = 0;
mLastDirectionChangeTime = 0;
lastX = 0;
lastY = 0;
lastZ = 0;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
这是我的OnCompletionListener代码。 包com.grifball.info;
import android.media.MediaPlayer;
public class OnCompletionListener {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
}
}
答案 0 :(得分:0)
我的猜测是你在这里混淆了interface
和class
。
您的OnCompletionListener
类完全没必要。您可以安全地删除它,除非您在代码中的其他位置使用它。
MediaPlayer.setOnCompletionListener()
将MediaPlayer.OnCompletionListener
类型的接口作为参数。此界面已经存在。
至于你的其余代码。您永远不会声明您的MediaPlayer对象mp
。它突然出现在onShake()
内。
public class HammerActivity extends Activity {
private ShakeDetector mShakeDetector;
private SensorManager mSensorManager;
// Declare the MediaPlayer object
private MediaPlayer mMediaPlayer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ShakeDetector initialization
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mShakeDetector = new ShakeDetector();
mShakeDetector.setOnShakeListener(new ShakeDetector.OnShakeListener() {
public void onShake() {
// Initialize media player
mMediaPlayer = MediaPlayer.create(HammerActivity.this, R.raw.hammer);
// Add OnCompletionListener to release the
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mMediaPlayer.release();
}
});
mMediaPlayer.start();
}
});
}
答案 1 :(得分:0)
获取以下代码并将其移至onCreate()
方法
mMediaPlayer = MediaPlayer.create(HammerActivity.this, R.raw.hammer);
// Add OnCompletionListener to release the
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mMediaPlayer.release();
}
});
另请查看SensorManager documentation
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
请注意:我只是剪切并粘贴了SensorManager文档中的代码。你必须使它适应你的代码;我的主要观点是你的onPause声明是错误的。