java - 在 Activity 之间传递加速度计值 - 应用程序崩溃

标签 java android android-activity

我尝试将摇动速度通过监听器 Activity 传递到主 Activity ,但代码无法正常工作。它说“不幸的是,应用程序已停止”

监听器代码:

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

}

主要 Activity 代码:

 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 无法运行。 谁能指出我可能做错了什么?

附注我对 Android 开发完全陌生

编辑: 日志猫:

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

最佳答案

MainActivity 不需要是抽象,也不需要实现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();
    }
}

最后一件事是对 AccReader 中的 mShakeListener 进行空检查,因为摇动事件似乎触发了多次,并且混淆了监听器。

当您调用 onShake 时,此代码应放入您的 onSensorChanged 方法中

if(mShakeListener != null)
    mShakeListener.onShake();

关于java - 在 Activity 之间传递加速度计值 - 应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32382638/

相关文章:

java - 如何修改ListView的ArrayList,但ListView和ArrayList在不同的Activity中

Android:无法在默认图片文件夹中创建目录

android - activity 和 fragment 之间的生命周期

android - Facebook 请求代码

java - 如何在之前不知道类的情况下使用 CSV HeaderColumnNameTranslateMappingStrategy

java - 在 O(1) 额外空间和 O(n) 时间内计算数组中所有元素的频率

java - 如何在Java中重绘

android - 如果包名称与 Play 商店中已有的其他人相似,Play 商店是否会不允许您上传 Android 应用程序?

Android 库 - 需要在库和主应用程序中添加编译库?

Android - 从 Activity 向上导航到 Fragment