2015-09-03 70 views
0

我嘗試將偵聽器活動的抖動速度傳遞給主要活動,但代碼不起作用。它說:「應用程序已停止不幸」在活動之間傳遞加速度計值 - 應用程序崩潰

監聽器代碼:

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

請張貼從logcat的 –

+0

整個錯誤@AndrewBrooke完成。 –

+0

你能張貼您的整個'MainActivity'代碼以及 –

回答

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

的最後一件事是在AccReadermShakeListener空校驗,因爲抖動事件似乎觸發多次,弄得聽衆。

此代碼應在你的onSensorChanged方法去當你調用onShake

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

很好的回答,但你可能要爲鏈接/解釋給提問者爲什麼用戶被錯誤使用'abstract'以及使用在最後的代碼段支架。 [我preffer這個解釋](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) – Bonatti

+0

謝謝安德魯。得到它的工作。另外,如果我想獲得突然加速的「快照」值,您是否可以建議進行更改? –

+0

非常感謝Bonatti。我通過解釋。這是非常需要的。 :) –