I have a home page that links to 4 different activities (pages). I have implemented the shake feature using the SensorEventListener
and it responds correctly but I can only use it to open up one activity at the moment for example: I can have it either shake once to open an activity or shake twice to open an activity but not both of those if
statements at once.
I've tried using if and else statements with boundaries because I know how to set the number of shakes but I don't understand how I can let the program detect to fully wait for how many shakes I do before it does a task.
private final SensorEventListener sensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
Intent tts = new Intent(context, ttsScreen.class);
Intent stt = new Intent(context, sttScreen.class);
Intent cbb = new Intent(context, cbbScreen.class);
Intent ocr = new Intent(context, ocrScreen.class);
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
acelLast = acelValue;
acelValue = (float) Math.sqrt((double) (x*x + y*y + z*z));
float difference = acelValue - acelLast;
shake = shake * 0.9f + difference;
if(shake > 12 && shake < 24 ) {
startActivity(tts);
}
else if (shake > 24 && shake < 36) {
startActivity(stt);
}
else if (shake > 36 && shake < 48) {
startActivity(cbb);
}
else if (shake > 48) {
startActivity(ocr);
}
}
In my onCreate
method i have the following:
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sm.registerListener(sensorListener,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
acelValue = SensorManager.GRAVITY_EARTH;
acelLast = SensorManager.GRAVITY_EARTH;
shake = 0.00f;
At the moment it will always open the startActivity(tts)
. I'm not sure what approach I need to take but I was thinking maybe a timer or something so that it fully checks how many shakes I do before opening an activity. Or is the if/else approach not the right way to do this?
Disclaimer: I'm not an android dev and have no experience with this. I have not tested my solution
Do not call startActivity()
until the user has stopped shaking the phone. You can find that out by looking at the last few differences in acceleration. If that is low enough to not count as shaking anymore, then finally you can call startActivity with the correct Intent.
private final SensorEventListener sensorListener = new SensorEventListener() {
private float differenceMedian = 0f;
@Override
public void onSensorChanged(SensorEvent event) {
Intent tts = new Intent(context, ttsScreen.class);
Intent stt = new Intent(context, sttScreen.class);
Intent cbb = new Intent(context, cbbScreen.class);
Intent ocr = new Intent(context, ocrScreen.class);
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
acelLast = acelValue;
acelValue = (float) Math.sqrt((double) (x*x + y*y + z*z));
float difference = acelValue - acelLast;
shake = shake * 0.9f + difference; // will increase shake as long as user continues to shake (I think?)
// differenceMedian will relatively slowly drop towards 0 when difference stays low
differenceMedian = (difference + differenceMedian ) /2;
if(differenceMedian < 1){ // depends. try to adjust the 1 here
if(shake > 12 && shake <= 24 ) { // please notice <= because what if shake is exactly 24? same for following else-ifs.
startActivity(tts);
}
else if (shake > 24 && shake <= 36) {
startActivity(stt);
}
else if (shake > 36 && shake <= 48) {
startActivity(cbb);
}
else if (shake > 48) {
startActivity(ocr);
}
}
}
Edit: as Gabe pointed out, the difference has to be very low over multiple calls of onSensorChanged() to ensure that the user has indeed stopped shaking their phone