我试图通过监听器活动将摇动速度传递给主要活动,但代码才刚刚起作用。它说"应用程序不幸停止了#34;
监听器代码:
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
/**
* Listener that detects shake gesture.
*/
public class AccReader implements SensorEventListener {
Activity foo;
SensorManager manager;
Sensor accelerometer;
private static final int MIN_FORCE = 10;
private static final int MIN_DIRECTION_CHANGE = 3;
private static final int MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE = 200;
private static final int MAX_TOTAL_DURATION_OF_SHAKE = 400;
private long mFirstDirectionChangeTime = 0;
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;
private float totalMovement;
public AccReader(Activity foo) {
this.foo = foo;
manager = (SensorManager) this.foo.getSystemService(Context.SENSOR_SERVICE);
accelerometer = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
manager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
}
/**
* Interface for shake gesture.
*/
public interface OnShakeListener {
/**
* Called when shake gesture is detected.
*/
void onShake();
}
public void setOnShakeListener(OnShakeListener listener) {
mShakeListener = listener;
}
public float getTotalMovement() {
return this.totalMovement;
}
@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
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) {
// checkk 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) {}
}
主要活动代码:
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
public abstract class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private AccReader mSensorListener;
private Sensor mAccelerometer;
AccReader acc;
private EditText output;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(new AccReader(this), mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
output = (EditText) findViewById(R.id.editText1);
acc = new AccReader(this);
mSensorListener.setOnShakeListener(new AccReader.OnShakeListener() {
@Override
public void onShake() {
refresh();
}
});
}
public void refresh() {
output.setText("X:" + acc.getTotalMovement());
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause() {
mSensorManager.unregisterListener(mSensorListener);
super.onPause();
}
代码已正确编译,但生成的APK无法运行。 有人能说清楚我做错了什么吗?
P.S。我对android开发是全新的
编辑: logcat的:
09 - 03 23: 51: 26.680 1936 - 1936 / lamegames.app I / art﹕Not late - enabling - Xcheck: jni(already on)
09 - 03 23: 51: 27.195 1936 - 1936 / lamegames.app D / AndroidRuntime﹕Shutting down VM---------beginning of crash
09 - 03 23: 51: 27.195 1936 - 1936 / lamegames.app E / AndroidRuntime﹕FATAL EXCEPTION: main
Process: lamegames.slapapp,
PID: 1936
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo {
lamegames.app / lamegames.app.MainActivity
}: java.lang.InstantiationException: class lamegames.app.MainActivity cannot be instantiated
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 2236)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java: 2390)
at android.app.ActivityThread.access$800(ActivityThread.java: 151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java: 1303)
at android.os.Handler.dispatchMessage(Handler.java: 102)
at android.os.Looper.loop(Looper.java: 135)
at android.app.ActivityThread.main(ActivityThread.java: 5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java: 372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 698)
Caused by: java.lang.InstantiationException: class lamegames.app.MainActivity cannot be instantiated
at java.lang.Class.newInstance(Class.java: 1587)
at``android.app.Instrumentation.newActivity(Instrumentation.java: 1066)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 2226)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java: 2390)
at android.app.ActivityThread.access$800(ActivityThread.java: 151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java: 1303)
at android.os.Handler.dispatchMessage(Handler.java: 102)
at android.os.Looper.loop(Looper.java: 135)
at android.app.ActivityThread.main(ActivityThread.java: 5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java: 372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 698)
09 - 03 23: 52: 10.917 1936 - 1943 / lamegames.app W / art﹕Suspending all threads took: 19.739ms
09 - 03 23: 52: 24.263 1936 - 1936 / lamegames.app I / Process﹕Sending signal.PID: 1936 SIG: 9
答案 0 :(得分:2)
MainActivity
不一定是abstract
,也不需要实施SensorEventListener
。我也不确定你为什么要使用两个AccReader
个对象。
以下是固定的MainActivity
代码:
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
AccReader acc;
private EditText output;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(new AccReader(this), mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
output = (EditText) findViewById(R.id.editText1);
acc = new AccReader(this);
acc.setOnShakeListener(new AccReader.OnShakeListener() {
@Override
public void onShake() {
refresh();
}
});
}
public void refresh() {
output.setText("X:" + acc.getTotalMovement());
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(acc,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause() {
mSensorManager.unregisterListener(acc);
super.onPause();
}
}
最后一件事是对mShakeListener
中AccReader
的空检查,因为震动事件似乎多次触发,并使听众感到困惑。
当您致电onSensorChanged
onShake
方法
if(mShakeListener != null)
mShakeListener.onShake();