Android - Launching an app with a shake - android

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

Related

chronometer not running in service

I am trying to run chronometer inside a Service. But I am not able to run it. I press a button in Activity and that event is passed to the Service. If the button in pressed then start the Chronometer but problem is setOnChronometerTickListener is called only once and it stops. Where am I making mistake? Here is my Service and Activity class:
Service class:
public class TimerService extends Service {
NotificationManager notificationManager;
NotificationCompat.Builder mBuilder;
Callbacks activity;
private final IBinder mBinder = new LocalBinder();
private Chronometer chronometer;
SharedPreferences sharedPreferences;
private int state = 0; //0 means stop state,1 means play, 2 means pause
private boolean running = false;
private long pauseOffSet = -1;
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
if (event.message) {
if (!running) {
if (pauseOffSet != -1) {
pauseOffSet = sharedPreferences.getLong("milli", -1);
}
chronometer.setBase(SystemClock.elapsedRealtime() - pauseOffSet);
chronometer.start();
state = 1;
pauseOffSet = 0;
running = true;
}
} else {
if (running) {
chronometer.stop();
pauseOffSet = SystemClock.elapsedRealtime() - chronometer.getBase();
state = 2;
running = false;
}
}
}
#Override
public void onCreate() {
super.onCreate();
EventBus.getDefault().register(this);
}
#Override
public void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
sharedPreferences = getSharedPreferences("myprefs", MODE_PRIVATE);
chronometer = new Chronometer(this);
state = sharedPreferences.getInt("state", 0);
chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
Log.e("TimerService","timer");
pauseOffSet = SystemClock.elapsedRealtime() - chronometer.getBase();
if (pauseOffSet >= 79200000) {
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.stop();
running = false;
// progressBar.setProgress(0);
} else {
chronometer.setText(setFormat(pauseOffSet));
// int convertTime = (int) pauseOffSet;
// progressBar.setProgress(convertTime);
}
if (activity != null) {
activity.updateClient(pauseOffSet);
}
}
});
if (state == 1) { // its in play mode
running = true;
chronometer.setBase(SystemClock.elapsedRealtime() - sharedPreferences.getLong("milli", 0));
chronometer.start();
} else if (state == 2) { //its in pause mode
running = false;
pauseOffSet = sharedPreferences.getLong("milli", -1);
long time = SystemClock.elapsedRealtime() - pauseOffSet;
chronometer.setBase(time);
int convertTime = (int) pauseOffSet;
// progressBar.setProgress(convertTime);
} else {
running = false;
}
//Do what you need in onStartCommand when service has been started
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
//returns the instance of the service
public class LocalBinder extends Binder {
public TimerService getServiceInstance() {
return TimerService.this;
}
}
//Here Activity register to the service as Callbacks client
public void registerClient(Activity activity) {
this.activity = (Callbacks) activity;
}
//callbacks interface for communication with service clients!
public interface Callbacks {
public void updateClient(long data);
}
String setFormat(long time) {
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
String hh = h < 10 ? "0" + h : h + "";
String mm = m < 10 ? "0" + m : m + "";
String ss = s < 10 ? "0" + s : s + "";
return hh + ":" + mm + ":" + ss;
}
}
This is my Activity class:
public class MainActivity extends AppCompatActivity implements View.OnClickListener, TimerService.Callbacks {
private static final String TAG = MainActivity.class.getSimpleName();
Chronometer tvTextView;
Button btnStart, btnStop;
private int state = 0; //0 means stop state,1 means play, 2 means pause
SharedPreferences sharedPreferences;
private boolean running = false;
private long pauseOffSet = -1;
ProgressBar progressBar;
Intent serviceIntent;
TimerService myService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTextView = findViewById(R.id.textview);
progressBar = findViewById(R.id.puzzleProgressBar);
btnStart = findViewById(R.id.button1);
btnStop = findViewById(R.id.button2);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
serviceIntent = new Intent(this, TimerService.class);
sharedPreferences = getSharedPreferences("myprefs", MODE_PRIVATE);
state = sharedPreferences.getInt("state", 0);
tvTextView.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
long time = SystemClock.elapsedRealtime() - chronometer.getBase();
pauseOffSet = time;
Log.e(TAG, "pauseOffSet " + pauseOffSet);
if (time >= 79200000) {
tvTextView.setBase(SystemClock.elapsedRealtime());
tvTextView.stop();
running = false;
progressBar.setProgress(0);
} else {
chronometer.setText(setFormat(time));
int convertTime = (int) time;
progressBar.setProgress(convertTime);
}
}
});
startService(serviceIntent); //Starting the service
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); //Binding to the service!
}
private ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
TimerService.LocalBinder binder = (TimerService.LocalBinder) service;
myService = binder.getServiceInstance();
myService.registerClient(MainActivity.this);
Log.e(TAG, "service connected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "service disconnected");
}
};
public void onClick(View v) {
if (btnStart == v) {
EventBus.getDefault().post(new MessageEvent(true));
} else if (btnStop == v) {
EventBus.getDefault().post(new MessageEvent(false));
}
}
#Override
protected void onStop() {
super.onStop();
sharedPreferences.edit().putLong("milli", pauseOffSet).commit();
sharedPreferences.edit().putInt("state", state).commit();
}
String setFormat(long time) {
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
String hh = h < 10 ? "0" + h : h + "";
String mm = m < 10 ? "0" + m : m + "";
String ss = s < 10 ? "0" + s : s + "";
return hh + ":" + mm + ":" + ss;
}
#Override
public void updateClient(long data) {
Log.d(TAG, "Data from service" + data);
}
}
The Chronometer is a View, that is, a UI element. You never add your Chronometer to any layout, I guess that's why it's never updating.
You could try using a CountDownTimer or a Handler / Runnable combination.
http://developer.android.com/reference/android/os/CountDownTimer.html http://developer.android.com/reference/android/os/Handler.html
Here's an example using Handler / Runnable, I've even thrown in a stopTimer() method for good measure:
private Handler timerHandler;
private Runnable timerRunnable;
// ...
#Override
public void onCreate() {
super.onCreate();
Log.d(LOG_TAG, "TimerService created");
timerHandler = new Handler();
timerRunnable = new Runnable() {
#Override
public void run() {
Log.d(LOG_TAG, "TICK");
timerHandler.postDelayed(timerRunnable, 1000);
}
};
}
public void startTimer() {
Log.d(LOG_TAG, "Timer started");
timerHandler.post(timerRunnable);
}
public void stopTimer() {
Log.d(LOG_TAG, "Timer stopped");
timerHandler.removeCallbacks(timerRunnable);
}
Here is a video which do not use Handler and directly implement the chronometer ,
Do check it out...
https://youtu.be/RLnb4vVkftc
Plus I had this problem I solved by removing
android:format="00:00"
from Chronometer in activity_main.xml
So my code looks like this :
<Chronometer
android:id="#+id/chronometer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:height="20sp"
android:foregroundGravity="fill_horizontal|top|bottom|center|fill_vertical|fill"
android:maxLines="2"
android:minLines="2"
android:textColor="#FFF"
android:textSize="40sp"
android:verticalScrollbarPosition="defaultPosition"
app:layout_constraintBottom_toBottomOf="#+id/progress_breathing"
app:layout_constraintEnd_toEndOf="#+id/progress_breathing"
app:layout_constraintStart_toStartOf="#+id/progress_breathing"
app:layout_constraintTop_toTopOf="#+id/progress_breathing"
app:layout_constraintVertical_bias="0.43" />

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

shake not working beyond certain value

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.

Categories

Resources