I have the following function for listening to acclerometer and magnetometer values:
// Storage for Sensor readings
public float[] mGravity = new float[3];
public float[] mGeomagnetic = new float[3];
public void registerSensors(Context context) {
// First, get an instance of the SensorManager
SensorManager sMan = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
// Second, get the sensor you're interested in
Sensor magnetField = sMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
// Get a reference to the accelerometer
Sensor accelerometer = sMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// Third, implement a SensorEventListener class
SensorEventListener magnetListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// do things if you're interested in accuracy changes
}
public void onSensorChanged(SensorEvent event) {
mGravity = new float[3];
//Log.i("LocationUpdater", "magnetometer updated");
System.arraycopy(event.values, 0, mGravity, 0, 3);
//Log.i("LocationUpdater", Float.toString(mGravity[0]));
}
};
SensorEventListener accelListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// do things if you're interested in accuracy changes
}
public void onSensorChanged(SensorEvent event) {
mGeomagnetic = new float[3];
//Log.i("LocationUpdater", "accelerometer updated");
System.arraycopy(event.values, 0, mGeomagnetic, 0, 3);
}
};
//mGravity[0] = 5;
// Finally, register your listener
sMan.registerListener(magnetListener, magnetField, SensorManager.SENSOR_DELAY_NORMAL);
sMan.registerListener(accelListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
Log.i("LocationUpdater","Listeners registered");
}
After that I'm trying to access mGravity in another method in the class:
public double getUserDirection() {
Log.i("LocationUpdater", Float.toString(mGravity[0]));
if (mGravity != null && mGeomagnetic != null) {
float rotationMatrix[] = new float[9];
...
}
However the values read from the sensor don't get written to the array and all values stay 0. Why is that?
All methods are called like this from another class:
SensorUpdater updater = new SensorUpdater();
updater.startBlukii(context);
updater.registerSensors(context);
double direction = updater.getUserDirection();
Log.i(LOG_TAG, Double.toString(direction));
I solved it by accessing the variables like this: LocationUpdater.mGravity inside the listeners, this seems to solve it.
public void onSensorChanged(SensorEvent event) {
System.arraycopy(event.values, 0, LocationUpdater.mGravity, 0, 3);
}
Related
I need to get values from a compass and do it in rxJava.
So I've made this code:
private void goCompass()
{
Observable.create(new Observable.OnSubscribe<SensorEventListener>()
{
SensorEventListener listener = null;
#Override
public void call(final Subscriber<? super SensorEventListener> subscriber)
{
Sensor gsensor;
Sensor msensor;
final float[] mGravity = new float[3];
final float[] mGeomagnetic = new float[3];
listener = new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent event) {
final float alpha = 0.97f;
Float azimuth = 0f;
synchronized (this) {
if(switchChecked == false) {
subscriber.onNext(listener);
subscriber.onCompleted();
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity[0] = alpha * mGravity[0] + (1 - alpha)
* event.values[0];
mGravity[1] = alpha * mGravity[1] + (1 - alpha)
* event.values[1];
mGravity[2] = alpha * mGravity[2] + (1 - alpha)
* event.values[2];
// mGravity = event.values;
// Log.e(TAG, Float.toString(mGravity[0]));
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// mGeomagnetic = event.values;
mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha)
* event.values[0];
mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha)
* event.values[1];
mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha)
* event.values[2];
// Log.e(TAG, Float.toString(event.values[0]));
}
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimuth = (float) Math.toDegrees(orientation[0]); // orientation
azimuth = (azimuth + 360) % 360;
Log.d("obs", "azimuth (rad): " + azimuth);
layout.setRotation(azimuth);
imageView.setRotation(-azimuth);
contlayout.setRotation(azimuth);
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
sensorManager = (SensorManager) getActivity()
.getSystemService(Context.SENSOR_SERVICE);
gsensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
msensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(listener, gsensor,
SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(listener, msensor,
SensorManager.SENSOR_DELAY_FASTEST);
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<SensorEventListener>() {
#Override
public void onCompleted()
{
}
#Override
public void onError(Throwable e)
{
}
#Override
public void onNext(SensorEventListener listener)
{
sensorManager.unregisterListener(listener);
}
});
}
and it works. However, I'm at the beginning of rxJava and I want to know if there are better ways to do this things:
I've tried to get the azimuth value in onNext() method any times, but it doesn't work
I want to make it asynchronously but I couldn't because registerListener works only in the mainThread() and so if I use Schedulers.io() I need also to do runOnUiThread() method.
There are other ways to do it?
Thank you for help
I'm currently programming an Android AR application and I have an issue with my Azimuth calculation depending of the initial device tilt.
I use the ROTATION_VECTOR sensor to get Azimuth, Altitude and Tilt.
When I launch my application and the phone is perpendicular with ground, I have the good azimuth from the North. When I launch the application and the phone is parallel to the ground, I have bad values. I have also strange values when I change device tilt.
This is my code :
public void onSensorChanged(SensorEvent event)
{
if (event.sensor.getType() == sensor.TYPE_ROTATION_VECTOR)
{
SensorManager.getRotationMatrixFromVector(rotationVectorMatrix, event.values);
SensorManager.remapCoordinateSystem(rotationVectorMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, rotationMatrix);
SensorManager.getOrientation(rotationMatrix, orientation);
...
}
}
To get azimuth, you can use an accelerometer and magnetic field sensors. You can use following code to log azimuth value.
public class MainActivity extends AppCompatActivity {
private int mAzimuth = 0; // degree
private SensorManager mSensorManager = null;
private Sensor mAccelerometer;
private Sensor mMagnetometer;
boolean haveAccelerometer = false;
boolean haveMagnetometer = false;
#Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager) getSystemService(Service.SENSOR_SERVICE);
this.mAccelerometer = this.mSensorManager.getDefaultSensor( Sensor.TYPE_ACCELEROMETER );
this.haveAccelerometer = this.mSensorManager.registerListener( mSensorEventListener, this.mAccelerometer, SensorManager.SENSOR_DELAY_GAME );
this.mMagnetometer = this.mSensorManager.getDefaultSensor( Sensor.TYPE_MAGNETIC_FIELD );
this.haveMagnetometer = this.mSensorManager.registerListener( mSensorEventListener, this.mMagnetometer, SensorManager.SENSOR_DELAY_GAME );
if ( haveAccelerometer && haveMagnetometer ) {
// ready to go
} else {
// unregister and stop
}
}
private SensorEventListener mSensorEventListener = new SensorEventListener() {
float[] gData = new float[3]; // accelerometer
float[] mData = new float[3]; // magnetometer
float[] rMat = new float[9];
float[] iMat = new float[9];
float[] orientation = new float[3];
public void onAccuracyChanged(Sensor sensor, int accuracy ) {}
#Override
public void onSensorChanged( SensorEvent event ) {
float[] data;
switch ( event.sensor.getType() ) {
case Sensor.TYPE_ACCELEROMETER:
gData = event.values.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
mData = event.values.clone();
break;
default: return;
}
if ( SensorManager.getRotationMatrix( rMat, iMat, gData, mData ) ) {
mAzimuth= (int) ( Math.toDegrees( SensorManager.getOrientation( rMat, orientation )[0] ) + 360 ) % 360;
Log.d("AzimuthTag", "Azimuth:"+mAzimuth);
}
}
};
}
Source
I'm trying to have a background service which reads the azimuth, pitch and roll of a phone and sends them over the network. I have already created a IntentService and the calculation code to calculate the orientation however I'm not quite sure how I am meant to register the background service as a event listener.
public class SocketService extends IntentService implements SensorEventListener {
Socket my_socket;
PrintWriter out;
float[] mGravity;
float[] mGeomagnetic;
float azimuth,pitch,roll;
public void onAccuracyChanged(Sensor s, int accuracy){
}
public void onSensorChanged(SensorEvent event){
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientationData[] = new float[3];
SensorManager.getOrientation(R, orientationData);
azimuth = orientationData[0];
pitch = orientationData[1];
roll = orientationData[2];
out.print("Hello");
out.flush();
}
}
}
public SocketService(){
super("Socket Service");
}
protected void onHandleIntent(Intent workIntent) {
try {
my_socket = new Socket(ip, 5000);
out = new PrintWriter(my_socket.getOutputStream());
}catch(Exception e){
Log.v("ERROR",e.getMessage());
}
}
}
I have tried inside the onHandleIntent to put
Sensor mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
mSensorManager.registerListener(this,mAccelerometer,SensorManager.SENSOR_DELAY_FASTEST);
mSensorManager.registerListener(this,mGravity,SensorManager.SENSOR_DELAY_FASTEST);
Which compiles however no data is detected at the other end of the socket (no data is detected even if I try to log it so there must be a problem with the actual SensorEventListener
Seems the problem was that
Sensor mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
is not the same as
Sensor mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Once I changed this, everything worked as a charm.
I'm making an app that tracks exercise movements based on orientation and accelerometer readings(the exercise movements are very slow). What I have is a strategy pattern kind of a situation where I have an abstract class for exercise movement and the concrete exercise movements implement the actual thing. Problem is, I am spawning threads to track different exercises in the onSensorChanged() method in my activity. since this is going to be called a lot of times, I don't know if my code will spawn as many threads. Do they get garbage collected?
Code:
public class WorkoutBuddy extends Activity implements SensorEventListener {
TextView t1, t2, t3, t4, t5, t6, t7;
SensorManager sensorManager;;
private Sensor sensorAccelerometer;
private Sensor sensorMagneticField;
private float[] valuesAccelerometer;
private float[] valuesMagneticField;
private float[] valuesOrientation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exercise_buddy);
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
sensorAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorMagneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
valuesAccelerometer = new float[3];
valuesMagneticField = new float[3];
valuesOrientation = new float[3];
matrixR = new float[9];
matrixI = new float[9];
matrixValues = new float[3];
//mediaPlayer = MediaPlayer.create(this, R.raw.first_position_confirmation);
}
#Override
protected void onPause() {
sensorManager.unregisterListener(this,sensorAccelerometer);
sensorManager.unregisterListener(this,sensorMagneticField);
super.onPause();
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
float[] orientation;
private float[] matrixR;
private float[] matrixI;
private float[] matrixValues;
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
valuesAccelerometer = lowPass(event.values.clone(), valuesAccelerometer);
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
valuesMagneticField = lowPass(event.values.clone(), valuesMagneticField);
}
if (valuesAccelerometer != null && valuesMagneticField != null) {
SensorManager.getRotationMatrix(matrixR, matrixI, valuesAccelerometer, valuesMagneticField);
if(true){
SensorManager.getOrientation(matrixR, matrixValues);
double azimuth = Math.toDegrees(matrixValues[0]);
double pitch = Math.toDegrees(matrixValues[1]);
double roll = Math.toDegrees(matrixValues[2]);
valuesOrientation[0]=(float) pitch;
valuesOrientation[1]=(float) roll;
valuesOrientation[0]=(float) azimuth;
Thread forExc1 = new Thread(new LeftShoulder(valuesAccelerometer, valuesOrientation, this));
Thread forExc2 = new Thread(new RightShoulder(valuesAccelerometer, valuesOrientation, this));
forExc1.run();
forExc2.run();
}
}
}
#Override
protected void onResume() {
sensorManager.registerListener(this,sensorAccelerometer,SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this,sensorMagneticField,SensorManager.SENSOR_DELAY_NORMAL);
super.onResume();
}
//Low pass filter used to smooth the sensor readings
protected float[] lowPass( float[] input, float[] output ) {
float ALPHA = 0.25f;
if ( output == null ) return input;
for ( int i=0; i<input.length; i++ ) {
output[i] = output[i] + ALPHA * (input[i] - output[i]);
}
return output;
}
}
package com.example.msapp2;
public abstract class ExerciseMovement implements Runnable{
protected float[] acc, ori;
protected boolean played = false;
}
package com.example.msapp2;
import android.content.Context;
import android.media.MediaPlayer;
public class LeftShoulder extends ExerciseMovement {
MediaPlayer mediaPlayer;
public LeftShoulder(float[] accelerometer, float[] orientation, Context context){
mediaPlayer = MediaPlayer.create(context, R.raw.first_position_confirmation);
acc = accelerometer;
//this.ori = orientation;
}
public void run(){
if(acc[0]> -10 && acc[0] < -8.5 && !played){
mediaPlayer.start();
played = true;
}
}
}
If you just override OnSensorChanged and output a Log.d , you'll see it's called hundreds, if not thousands, of times per second.
I suggest you the opposite approach: Create just one thread to process in background the different received events, then feed such thread from onSensorChanged.
Implement kind of an event queue in the thread. Assume thousands of events will arrive, constantly.
SOmething like:
private class ShoulderMovementProcessorThread extends Thread {
.....
// this will be called from the UI thread, just add event to the (synchronized) queue.
public void publish (int[] valuesAccelerometer, int[] valuesWhatever) {
add_event_to_queue();
}
// this is the typical event loop where you read one from the queue, process it, then wait for the next
public void run() {
-> get event
-> process event
-> wait for next event
}
}
ShoulderMovementProcessorThread mShoulderProcessor=new ShoulderMovementProcessorThread(...);
#Override
public void onSensorChanged(SensorEvent event) {
decodeEvent (event); // fills up azimuth, roll, etc.
mShoulderProcessor.publish(valuesAccelerometer, valuesWhatever);
}
// decode an event
private void decodeEvent (SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
valuesAccelerometer = lowPass(event.values.clone(), valuesAccelerometer);
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
valuesMagneticField = lowPass(event.values.clone(), valuesMagneticField);
}
if (valuesAccelerometer != null && valuesMagneticField != null) {
SensorManager.getRotationMatrix(matrixR, matrixI, valuesAccelerometer, valuesMagneticField);
if(true){
SensorManager.getOrientation(matrixR, matrixValues);
double azimuth = Math.toDegrees(matrixValues[0]);
double pitch = Math.toDegrees(matrixValues[1]);
double roll = Math.toDegrees(matrixValues[2]);
valuesOrientation[0]=(float) pitch;
valuesOrientation[1]=(float) roll;
valuesOrientation[0]=(float) azimuth;
}
}
}
I implemented something similar recently:
public class DBWorkerThread implements Runnable
{
private SensorEnum sensorType;
private LinkedBlockingQueue<float[]> sensorData;
private DBService dbService;
public DBWorkerThread(SensorEnum type, DBService dbService)
{
this.sensorType = type;
this.dbService = dbService;
this.sensorData = new LinkedBlockingQueue<float[]>();
}
/**
* Add data to queue
* #param values
*/
public void addDataToProcess(float[] values)
{
if (sensorData.size() < sensorData.remainingCapacity())
{
try
{
this.sensorData.put(values);
}
catch (Exception ex)
{
LogService.log("Error adding queue: " + ex.getMessage());
}
LogService.log("Added to queue. Size: " + sensorData.size());
}
}
/**
* Processes queue of data
*/
#Override
public void run()
{
// Moves the current Thread into the background
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
while (sensorData.size() > 0)
{
try
{
float[] values = sensorData.take();
storeData(values);
}
catch (Exception ex)
{
LogService.log("Error in queue: " + ex.getMessage());
}
}
}
/**
* Store data to database
* #param values
*/
private void storeData(float[] values)
{
// store data
}
}
Hopes this helps
I want to use the accelerometer sensor to keep track when a user makes sudden moves.
This service should be started via activity and keep running indefinitely even if application is terminated (exits).
Currently everything works fine while app is alive, once the app closed, i can still see the service runs but i don't get any signals from him anymore.
Can someone help keep the service alive with signals?
Please look at the code i have.
MainActivity.java
public class MainActivity extends ActionBarActivity implements CordovaInterface {
private boolean mAlternateTitle = false;
private boolean bound;
private boolean volumeupBound;
private boolean volumedownBound;
String TAG = "MainActivity-ActionBarTest";
private IPlugin activityResultCallback;
private Object activityResultKeepRunning;
private Object keepRunning;
CordovaWebView mainView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//startService(new Intent(getBaseContext(), FirstService.class));
startService(new Intent(getApplicationContext(), MainAccelerometer.class));
mainView = (CordovaWebView) findViewById(R.id.mainView);
mainView.loadUrl("file:///android_asset/www/index.html");
}
MainAccelerometer.java
public class MainAccelerometer extends Service implements AccelerometerListener{
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
public IBinder onBind(Intent arg0)
{
return null;
}
public void onCreate() {
super.onCreate();
//Check device supported Accelerometer senssor or not
if (AccelerometerManager.isSupported(getApplicationContext())) {
//Start Accelerometer Listening
AccelerometerManager.startListening(this);
}
}
public void onAccelerationChanged(float x, float y, float z) {
// TODO Auto-generated method stub
}
public void onShake(float force) {
// Called when Motion Detected
//Toast.makeText(getBaseContext(), "Motion detected", Toast.LENGTH_SHORT).show();
Log.d("Test", "shake");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("Sensor", "Service distroy");
//Check device supported Accelerometer senssor or not
if (AccelerometerManager.isListening()) {
//Start Accelerometer Listening
AccelerometerManager.stopListening();
//Toast.makeText(getBaseContext(), "onDestroy Accelerometer Stoped", Toast.LENGTH_LONG).show();
}
}
}
AccelerometerManager.java
public class AccelerometerManager {
private static Context aContext=null;
/** Accuracy configuration */
private static float threshold = 20.0f;
private static int interval = 2000;
private static Sensor sensor;
private static SensorManager sensorManager;
// you could use an OrientationListener array instead
// if you plans to use more than one listener
private static AccelerometerListener listener;
/** indicates whether or not Accelerometer Sensor is supported */
private static Boolean supported;
/** indicates whether or not Accelerometer Sensor is running */
private static boolean running = false;
/**
* Returns true if the manager is listening to orientation changes
*/
public static boolean isListening() {
return running;
}
/**
* Unregisters listeners
*/
public static void stopListening() {
running = false;
try {
if (sensorManager != null && sensorEventListener != null) {
sensorManager.unregisterListener(sensorEventListener);
}
} catch (Exception e) {}
}
/**
* Returns true if at least one Accelerometer sensor is available
*/
public static boolean isSupported(Context context) {
aContext = context;
if (supported == null) {
if (aContext != null) {
sensorManager = (SensorManager) aContext.
getSystemService(Context.SENSOR_SERVICE);
// Get all sensors in device
List<Sensor> sensors = sensorManager.getSensorList(
Sensor.TYPE_ACCELEROMETER);
supported = new Boolean(sensors.size() > 0);
} else {
supported = Boolean.FALSE;
}
}
return supported;
}
/**
* Configure the listener for shaking
* #param threshold
* minimum acceleration variation for considering shaking
* #param interval
* minimum interval between to shake events
*/
public static void configure(int threshold, int interval) {
AccelerometerManager.threshold = threshold;
AccelerometerManager.interval = interval;
}
/**
* Registers a listener and start listening
* #param accelerometerListener
* callback for accelerometer events
*/
public static void startListening( AccelerometerListener accelerometerListener )
{
sensorManager = (SensorManager) aContext.
getSystemService(Context.SENSOR_SERVICE);
// Take all sensors in device
List<Sensor> sensors = sensorManager.getSensorList(
Sensor.TYPE_ACCELEROMETER);
if (sensors.size() > 0) {
sensor = sensors.get(0);
// Register Accelerometer Listener
running = sensorManager.registerListener(
sensorEventListener, sensor,
SensorManager.SENSOR_DELAY_GAME);
listener = accelerometerListener;
}
}
/**
* Configures threshold and interval
* And registers a listener and start listening
* #param accelerometerListener
* callback for accelerometer events
* #param threshold
* minimum acceleration variation for considering shaking
* #param interval
* minimum interval between to shake events
*/
public static void startListening(
AccelerometerListener accelerometerListener,
int threshold, int interval) {
configure(threshold, interval);
startListening(accelerometerListener);
}
/**
* The listener that listen to events from the accelerometer listener
*/
private static SensorEventListener sensorEventListener =
new SensorEventListener() {
private long now = 0;
private long timeDiff = 0;
private long lastUpdate = 0;
private long lastShake = 0;
private float x = 0;
private float y = 0;
private float z = 0;
private float lastX = 0;
private float lastY = 0;
private float lastZ = 0;
private float force = 0;
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
public void onSensorChanged(SensorEvent event) {
// use the event timestamp as reference
// so the manager precision won't depends
// on the AccelerometerListener implementation
// processing time
now = event.timestamp;
x = event.values[0];
y = event.values[1];
z = event.values[2];
// if not interesting in shake events
// just remove the whole if then else block
if (lastUpdate == 0) {
lastUpdate = now;
lastShake = now;
lastX = x;
lastY = y;
lastZ = z;
Toast.makeText(aContext,"No Motion detected", Toast.LENGTH_SHORT).show();
} else {
timeDiff = now - lastUpdate;
if (timeDiff > 0) {
/*force = Math.abs(x + y + z - lastX - lastY - lastZ)
/ timeDiff;*/
//force = Math.abs(x + y + z - lastX - lastY - lastZ);
force = Math.abs(x - lastX);
if (Float.compare(force, threshold) >0 ) {
//Toast.makeText(Accelerometer.getContext(), (now-lastShake)+" >= "+interval, 1000).show();
if (now - lastShake >= interval) {
// trigger shake event
listener.onShake(force);
}
else
{
//Toast.makeText(aContext,"No Motion detected", Toast.LENGTH_SHORT).show();
}
lastShake = now;
}
lastX = x;
lastY = y;
lastZ = z;
lastUpdate = now;
}
else
{
//Toast.makeText(aContext,"No Motion detected", Toast.LENGTH_SHORT).show();
}
}
// trigger change event
listener.onAccelerationChanged(x, y, z);
}
};
}
AccelerometerListener.java
public interface AccelerometerListener {
public void onAccelerationChanged(float x, float y, float z);
public void onShake(float force);
}