shake not working beyond certain value - android

I want to measure a big shake(Eg: Measure when bike or car gets into accident. I want to measure that phone shake). I have code for play audio when my mobile is shaken. But when I changed SHAKE_THRESHOLD value to a high level it wasn't working.
Is it possible to measure big shake.
Mycode:
public class ShakeActivity extends Activity implements SensorListener{
// For shake motion detection.
private MediaPlayer mPlayer1;
private SensorManager sensorMgr;
private long lastUpdate = -1;
private float x, y, z;
private float last_x, last_y, last_z;
private static final int SHAKE_THRESHOLD = 8000;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// other initializations
// start motion detection
sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
boolean accelSupported = sensorMgr.registerListener(this,
SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_GAME);
if (!accelSupported) {
// on accelerometer on this device
sensorMgr.unregisterListener(this,
SensorManager.SENSOR_ACCELEROMETER);
}
}
protected void onPause() {
if (sensorMgr != null) {
sensorMgr.unregisterListener(this,
SensorManager.SENSOR_ACCELEROMETER);
sensorMgr = null;
}
super.onPause();
}
#Override
public void onAccuracyChanged(int arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(int sensor, float[] values) {
// TODO Auto-generated method stub
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate)> 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z)
/ diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
// yes, this is a shake action! Do something about it!
MediaPlayer mPlayer1 = MediaPlayer.create(this, R.raw.hello);
try {
mPlayer1.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mPlayer1.start();
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
}

Go to API Demos application -> OS -> Sensors there is a diagram there. Shake your device and look which sensor shows your device changes better and satisfy your needs.

Related

Android - Launching an app with a shake

I'm a newbie to this field of android development. I'm developing an app which I need to be launched by shaking the device. How can I get this thing done? I read many threads and tried out several codes. but non of them worked. Please be kind enough to come up with the full code (from top to bottom) of particular file(or files). So that I'll be able to understand where exactly that I need to change in my code. Thank you!
Try this, First create your Service
public class ShakeService extends Service implements SensorEventListener {
private SensorManager sensorMgr;
private Sensor acc;
private long lastUpdate = -1;
private float x, y, z;
private float last_x, last_y, last_z;
private static final int SHAKE_THRESHOLD = 1100;
#Override
public void onCreate() {
Toast.makeText(this,
"Service Started", Toast.LENGTH_SHORT).show();
sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
acc=sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
boolean accelSupported= sensorMgr.registerListener((SensorEventListener) this, acc, SensorManager.SENSOR_DELAY_GAME);
long curTime11 = System.currentTimeMillis();
if (!accelSupported) {
// on accelerometer on this device
sensorMgr.unregisterListener((SensorEventListener) this,acc);
}
super.onCreate();
}
protected void onPause() {
if (sensorMgr != null) {
sensorMgr.unregisterListener((SensorEventListener) this,acc);
sensorMgr = null;
}
return;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
if (sensorMgr != null) {
sensorMgr.unregisterListener((SensorEventListener) this,acc);
sensorMgr = null;
}
stopSelf();
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = sensorEvent.values[SensorManager.DATA_X];
y = sensorEvent.values[SensorManager.DATA_Y];
z = sensorEvent.values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
Log.d("sensor", "shake detected w/ speed: " + speed);
Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show();
Intent myIntent= new Intent(this, MyActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
/ startActivity(myIntent);
////Here start your activity and your application will be started
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}
And make sure to declare your service in manifest
<service
android:name=".ShakeService"
android:enabled="true"
android:exported="true"></service>
Now in your activity start service as
startService(new Intent(MainActivity.this,ShakeService.class));

How to capture orientation values after a certain time an activity has started

I am trying to read the orientation and accelerometer readings 5 seconds after the Activity has started. I am tracking the sensor readings as they are changing but 5 seconds into the activity, I want to capture certain special readings in a certain position. I want all other processes to work as normal in the meantime. Here is my activity code, Am I doing this right?
public class WorkoutBuddy extends Activity implements SensorEventListener {
TextView t1, t2, t3;
Compass myCompass;
SensorManager sensorManager;;
private Sensor sensorAccelerometer;
private Sensor sensorMagneticField;
private float[] valuesAccelerometer;
private float[] valuesMagneticField;
private float[] startingPositionAccelerometer;
private float[] startingPositionMagneticField;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exercise_buddy);
t1 = (TextView)findViewById(R.id.textView1);
t2 = (TextView)findViewById(R.id.textView2);
t3 = (TextView)findViewById(R.id.textView3);
myCompass = (Compass) findViewById(R.id.mycompass);
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];
matrixR = new float[9];
matrixI = new float[9];
matrixValues = new float[3];
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
sensorManager.unregisterListener(this,sensorAccelerometer);
sensorManager.unregisterListener(this,sensorMagneticField);
super.onPause();
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
float azimuth,pitch,roll;
private float[] matrixR;
private float[] matrixI;
private float[] matrixValues;
boolean startingPosition = false;
#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]);
t1.setText("Azimuth: " + String.format("%.4f", azimuth));
t2.setText("Pitch: " + String.format("%.4f", pitch));
t3.setText("Roll: " + String.format("%.4f", roll));
myCompass.update(matrixValues[0]);
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
if(startingPosition == false){
startingPositionAccelerometer= valuesAccelerometer;
startingPositionMagneticField= valuesMagneticField;
startingPosition = true;
}
}
},
5000
);
}
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
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;
}
}
You can use a Handler to perform a delayed action.
public void onResume() {
super.onResume();
new Handler().postDelayed(new Runnable() {
public void run() {
//Record readings here.
}
}, 5000);
I would prefer to use ScheduledExecutorService like below...
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); // 2 - number of thread in pool
// run every 5 seconds
executorService.scheduleAtFixedRate(new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
// do your UI stuff here..
}
});
}
}, 0, 5, TimeUnit.SECONDS);

LightSensor too much data

I have a LightSensor which broadcasts changes. Basically it is broadcasting on every sampling even if there is no change from 0. How should I get the Sensor to only broadcast basically an ON/OFF value. For example if lux > 0 then light is ON else lux = 0 so light is OFF.
sendLuxUpdate():
public class LightSensor extends Service implements SensorEventListener {
private SensorManager mSensorManager;
public Sensor LightSensor;
public static Float lightLux;
TextView tvLightSensorLux;
public String Lux;
public void onCreate() {
Log.d("LightSensor", "OnCreate");
// Get an instance of the sensor service
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor LightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
// Test to see if Light Sensor is available
if (LightSensor != null) {
mSensorManager.registerListener(this, LightSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
public void onStartCommand() {
Log.d("LightSensor", "OnStartCommand");
}
/**
* protected void onResume() { mSensorManager.registerListener(this,
* LightSensor, SensorManager.SENSOR_DELAY_NORMAL); // super.onResume(); }
*
* protected void onPause() { mSensorManager.unregisterListener(this,
* LightSensor); // super.onPause(); }
**/
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
lightLux = event.values[0]; // Final output of this sensor.
Lux = String.valueOf(lightLux);
if (lightLux > 0) {
Log.d("LightSensor", Lux);
sendLuxUpdate();
} else {
float lightLux = 0;
sendLuxUpdate();
}
}
private void sendLuxUpdate() {
Log.d("sender", "Broadcasting message " + Lux);
Intent intent = new Intent("LuxUpdate");
intent.putExtra("Lux", Lux);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
stopSelf();
mSensorManager.unregisterListener(this, LightSensor);
}
}
Problem is that Sensors send you raw analog data. So they are continuous and data is raw. Or if you are using other sensors too, this method might be called by other sensors. So check type of sensor also.
public void onSensorChanged(SensorEvent event) {
lightLux = event.values[0]; // Final output of this sensor.
Lux = String.valueOf(lightLux);
if(event.sensor.getType()==Sensor.TYPE_LIGHT){
final float currentReading = event.values[0];
if (currentReading > 0){
//ON
}
else
{//OFF
}
}
}
Also you will see change in value everytime, because it sends too detailed value as it is raw data. You can cast it to int if you don't want this.
int value= (int) event.values[0];
Hope it helps! Good luck

Intent Service getting killed after sometime

I have implemented an intent service in my application, the purpose of which is to monitor the device's shake on a continuous basis.According to the requirement,whenever a shake is detected ,this info should be sent to the app server.
When I started this implementation I had a dilemma on whether to use service or intent service but I chose the latter.Currently,I am able to detect the shake and this info is getting relayed to my app server,but sometimes from 15 min to 2 hour(post starting the app) I notice that this intent service no longer seems to detect any shakes(seems its getting killed on its own).
Here is my code:
public class TheftAlertService1 extends IntentService {
/* The connection to the hardware */
private SensorManager mySensorManager;
/* Here we store the current values of acceleration, one for each axis */
private float xAccel;
private float yAccel;
private float zAccel;
/* And here the previous ones */
private float xPreviousAccel;
private float yPreviousAccel;
private float zPreviousAccel;
private static int SyncRunningFlag = 0;
private double latitude; // latitude
private double longitude; // longitude
/* Used to suppress the first shaking */
private boolean firstUpdate = true;
/* What acceleration difference would we assume as a rapid movement? */
private final float shakeThreshold = .75f;
/* Has a shaking motion been started (one direction) */
private boolean shakeInitiated = false;
public TheftAlertService1() {
super("TheftAlertService1");
Log.d("TheftAlertService1", "inside constr");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent arg0) {
mySensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // (1)
mySensorManager.registerListener(mySensorEventListener,
mySensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL); // (2)
Log.d("TheftAlertService1", "Inside shake onHandleEvent");
}
/* The SensorEventListener lets us wire up to the real hardware events */
private final SensorEventListener mySensorEventListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent se) {
updateAccelParameters(se.values[0], se.values[1], se.values[2]); // (1)
if ((!shakeInitiated) && isAccelerationChanged()) { // (2)
shakeInitiated = true;
} else if ((shakeInitiated) && isAccelerationChanged()) { // (3)
executeShakeAction();
} else if ((shakeInitiated) && (!isAccelerationChanged())) { // (4)
shakeInitiated = false;
}
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
};
/* Store the acceleration values given by the sensor */
private void updateAccelParameters(float xNewAccel, float yNewAccel,
float zNewAccel) {
/*
* we have to suppress the first change of acceleration, it results from
* first values being initialized with 0
*/
if (firstUpdate) {
xPreviousAccel = xNewAccel;
yPreviousAccel = yNewAccel;
zPreviousAccel = zNewAccel;
firstUpdate = false;
} else {
xPreviousAccel = xAccel;
yPreviousAccel = yAccel;
zPreviousAccel = zAccel;
}
xAccel = xNewAccel;
yAccel = yNewAccel;
zAccel = zNewAccel;
}
/*
* If the values of acceleration have changed on at least two axises, we are
* probably in a shake motion
*/
private boolean isAccelerationChanged() {
float deltaX = Math.abs(xPreviousAccel - xAccel);
float deltaY = Math.abs(yPreviousAccel - yAccel);
float deltaZ = Math.abs(zPreviousAccel - zAccel);
return (deltaX > shakeThreshold && deltaY > shakeThreshold)
|| (deltaX > shakeThreshold && deltaZ > shakeThreshold)
|| (deltaY > shakeThreshold && deltaZ > shakeThreshold);
}
private void executeShakeAction() {
Log.d("TheftAlertService1", "inside executeShakeAction");
if (SyncRunningFlag == 0)
new SendTheftAlertToBackend().execute();
}
/******************************************************************************************************/
class SendTheftAlertToBackend extends AsyncTask<String, String, String> implements LocationListener{
JSONParser jsonParser = new JSONParser();
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String device_id = tm.getDeviceId();
#Override
protected void onPreExecute() {
super.onPreExecute();
SyncRunningFlag = 1;
LocationManager locationManager;
Location location; // location
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.d("TheftAlertService1", "Latitude - " +latitude + "longitude - "+longitude);
}
}
Log.d("TheftAlertService1", "Sending Theft Alert to app server");
}
protected String doInBackground(String... args) {
String theft_alert_time = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance()
.getTime());
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("device_id", device_id));
params.add(new BasicNameValuePair("theft_alert_time",theft_alert_time));
params.add(new BasicNameValuePair("theft_alert_longitude","lon -" + longitude));
params.add(new BasicNameValuePair("theft_alert_latitude","lat -" + latitude));
// getting JSON Object
JSONObject json = jsonParser.makeHttpRequest(
AppConstants.url_theft_alert, "POST", params);
try {
Log.d("TheftAlertService1,Response from server : ",
json.toString());
} catch (Exception e1) {
e1.printStackTrace();
SyncRunningFlag = 0;
}
// check for success tag
try {
int success = json.getInt(AppConstants.TAG_SUCCESS);
String tagDeviceId = json.getString(AppConstants.TAG_DEVICE_ID);
if (success == 1 && tagDeviceId.equals(device_id)) {
Log.d("TheftAlertService1",
"Theft Alert successfully logged in server");
SyncRunningFlag = 0;
} else {
Log.d("TheftAlertService1",
"Failed to log Theft Alert in server");
SyncRunningFlag = 0;
}
} catch (Exception e) {
e.printStackTrace();
SyncRunningFlag = 0;
}
return null;
}
protected void onPostExecute(String file_url) {
Log.d("TheftAlertService1", "inside onPost of async task");
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
}
This is what I have tried till now :
1) I have overridden onStartCommand and gave its return as START REDELIVER INTENT
2) I tried to make the intent service in foreground.
But nethier of these two options have 'sustained' the continuous background monitoring of shake on my device.
Following code I tried but in vain:
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
final int myID = 1234;
//The intent to launch when the user clicks the expanded notification
Intent intentService = new Intent(this, Staff.class);
intentService.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intentService, 0);
//This constructor is deprecated. Use Notification.Builder instead
Notification notice = new Notification(R.drawable.ic_launcher, "Ticker text", System.currentTimeMillis());
//This method is deprecated. Use Notification.Builder instead.
notice.setLatestEventInfo(this, "Title text", "Content text", pendIntent);
notice.flags |= Notification.FLAG_NO_CLEAR;
startForeground(myID, notice);
return START_REDELIVER_INTENT;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("TheftAlertService1","Service got killed");
}
What is it that I am doing wrong? What should I do to make my intent service to run continuously in the background(and sense shakes forever).
Any help is appreciated.Thanks !
As Pankaj Kumar suggested I created my shake detection inside a service instead of an IntentService (as I was trying before,which used to fail to detect the shakes after sometime).I tested my service for 48 hours straight on devices(like nexus4,galaxy grand) and was able to detect shakes for the above tested period whenever the device was shaked.
To make the service live indefinitely I made the service foreground and returned START_STICKY as shown below.Following is the full code:
public class ShakeService extends Service {
/* The connection to the hardware */
private SensorManager mySensorManager;
/* Here we store the current values of acceleration, one for each axis */
private float xAccel;
private float yAccel;
private float zAccel;
/* And here the previous ones */
private float xPreviousAccel;
private float yPreviousAccel;
private float zPreviousAccel;
/* Used to suppress the first shaking */
private boolean firstUpdate = true;
/* What acceleration difference would we assume as a rapid movement? */
private final float shakeThreshold = .75f;
/* Has a shaking motion been started (one direction) */
private boolean shakeInitiated = false;
private BackgroundThread backGroundThread = null;
SensorEventListener mySensorEventListener;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
if (backGroundThread == null) {
backGroundThread = new BackgroundThread();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (backGroundThread == null)
backGroundThread = new BackgroundThread();
if ((backGroundThread.getState() == Thread.State.NEW) || (backGroundThread.getState() == Thread.State.TERMINATED)) {
if (backGroundThread.getState() == Thread.State.TERMINATED)
backGroundThread = new BackgroundThread();
backGroundThread.start();
Notification localNotification = new Notification(R.drawable.ic_launcher, "", System.currentTimeMillis());
localNotification.setLatestEventInfo(this,AppConstants.NOTIFICATION_NAME,AppConstants.NOTIFICATION_DESCRIPTION, null);
localNotification.flags = Notification.FLAG_NO_CLEAR;
startForeground(377982, localNotification);
mySensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mySensorManager.registerListener(mySensorEventListener,mySensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
Log.d("ShakeService", "Inside shake onStartCommand");
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
BackgroundThread.yield();
backGroundThread = null;
}
class BackgroundThread extends Thread {
#Override
public void run() {
/* The SensorEventListener lets us wire up to the real hardware events */
mySensorEventListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent se) {
updateAccelParameters(se.values[0], se.values[1], se.values[2]);
if ((!shakeInitiated) && isAccelerationChanged()) {
shakeInitiated = true;
} else if ((shakeInitiated) && isAccelerationChanged()) {
executeShakeAction();
} else if ((shakeInitiated) && (!isAccelerationChanged())) {
shakeInitiated = false;
}
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
/* Store the acceleration values given by the sensor */
private void updateAccelParameters(float xNewAccel, float yNewAccel,float zNewAccel) {
/*
* we have to suppress the first change of acceleration, it results from
* first values being initialized with 0
*/
if (firstUpdate) {
xPreviousAccel = xNewAccel;
yPreviousAccel = yNewAccel;
zPreviousAccel = zNewAccel;
firstUpdate = false;
} else {
xPreviousAccel = xAccel;
yPreviousAccel = yAccel;
zPreviousAccel = zAccel;
}
xAccel = xNewAccel;
yAccel = yNewAccel;
zAccel = zNewAccel;
}
/*
* If the values of acceleration have changed on at least two axises, we are
* probably in a shake motion
*/
private boolean isAccelerationChanged() {
float deltaX = Math.abs(xPreviousAccel - xAccel);
float deltaY = Math.abs(yPreviousAccel - yAccel);
float deltaZ = Math.abs(zPreviousAccel - zAccel);
return (deltaX > shakeThreshold && deltaY > shakeThreshold) || (deltaX > shakeThreshold && deltaZ > shakeThreshold) || (deltaY > shakeThreshold && deltaZ > shakeThreshold);
}
private void executeShakeAction() {
Log.d("ShakeService", "inside executeShakeAction");
// Or do something like post the shake status to app server
}
};
}
}
}
newIntent(GcmIntentService.this,TheftAlertService1.class); startService(theftAlertIntent);
replace this with
newIntent(getApplicationContext(),TheftAlertService1.class); startService(theftAlertIntent);

SensorEventListener in combination with Timer-Thread

I want to write an Android program which lets the user set up a countdown timer. After the user pushes the "Start-Button" the countdown is running. While the countdown is running, the phone should recognize the acceleration of the device.
If time is up, or the device was shaken to much a new activity should be loaded..
At my device (S4) the code is running quite well, only the countdown timer doesn't get closed after the device has been shaken to much, so the run-method will be activated suddenly. On other device (S2) the new activity is started directly after pushing the button. How could this be?
I think I made a mistake with the run-method and I am not sure if I understand the idea about setting threads correctly.
Here is my code:
public class WaitingForBomb extends Activity {
float sensibility = 2.5f;
boolean isOver = false;
private SensorManager mSensorManager;
private float mAccel; // Beschleunigung
private float mAccelCurrent; // aktuelle Beschleunigung (in Verbindung mit
// Erdanziehung)?
private float mAccelLast; // letzte Beschleunigung (in Verbindung mit
// Erdanziehung)?
TextView anzeige;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.waiting);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
mAccel = 0.00f;
mAccelCurrent = SensorManager.GRAVITY_EARTH;
mAccelLast = SensorManager.GRAVITY_EARTH;
// Sleep-Timer
Thread bombTimer = new Thread() {
public void run() {
while (isOver = false) {
try {
// Intent-Übergabe des Counters
Intent mIntent = getIntent();
int counterValue = mIntent
.getIntExtra("pushCounter", 0);
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(counterValue);
sleep(counterValue);
isOver = true;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
isOver = true;
}
}
}
};
bombTimer.start();
}
// Verhindert, dass die "Back-Taste" erkannt wird und somit das Spiel
// vorzeitig beendet wird.
#Override
public void onBackPressed() {
}
private final SensorEventListener mSensorListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent se) {
float x = se.values[0];
float y = se.values[1];
float z = se.values[2];
mAccelLast = mAccelCurrent;
mAccelCurrent = (float) Math.sqrt((double) (x * x + y * y + z * z));
float delta = mAccelCurrent - mAccelLast;
mAccel = mAccel * 0.9f + delta; // perform low-cut filter
SharedPreferences getPrefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
boolean checkSense1 = getPrefs.getBoolean("sensi1", true);
boolean checkSense2 = getPrefs.getBoolean("sensi2", false);
if (checkSense1 == true) {
sensibility = 1.25f;
}
if (checkSense2 == true) {
sensibility = 0.75f;
}
// Prüft die Beschleunigung
if (mAccel > sensibility) {
Intent gameOver = new Intent("android.intent.action.BOOM");
startActivity(gameOver);
}
if (isOver == true) {
Intent gameOver = new Intent("android.intent.action.BOOM");
startActivity(gameOver);
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
#Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
mSensorManager.unregisterListener(mSensorListener);
super.onPause();
finish();
}
}
Just update your while condition
while (!isOver) {
}

Categories

Resources