简体   繁体   中英

Logics issue while using accelerometer

I am trying to make an app like "Heads up" just for more exercising!!

but now I faced some logical problem in using accelerometer in my app.

I want the app toast "correct" when it tilt's down (accelerometer gives -7 in this position) and toast "wrong" when tilt's up (accelerometer gives 7 or more in this position).

But the problem was that app toast many times repeatedly in each position. so I used a boolean (isToasted) to make the app toast once in each of those position. But now it doesn't toast at all!

where is my problem and what should i do?

this is a part of my codes:

Boolean isToasted = false;

@Override
public void onSensorChanged(SensorEvent event) {
    int sensorValue = (int) event.values[2];

    while (isToasted) {
        switch (sensorValue) {
            case 7: {
                Toast.makeText(find_word2.this, "wrong", Toast.LENGTH_SHORT).show();
                isToasted = true;
                break;
            }
            case -7: {
                Toast.makeText(find_word2.this, "correct", Toast.LENGTH_SHORT).show();
                isToasted = true;
                break;
            }
        }
    }
    if (sensorValue == 0) isToasted = false;  //sensorValue = 0 means device is not tilted and it's in direct position.
}

The difference between do-while and while is that do-while evaluates its expression at the bottom of the loop instead of the top. Therefore, the statements within the do block are always executed at least once.

The reason it would display the Toast multiple times in each position is because a SensorEvent can occur multiple times at a single position:

Note that "on changed" is somewhat of a misnomer, as this will also be called if we have a new reading from a sensor with the exact same sensor values (but a newer timestamp).

Therefore, every time there is a SensorEvent that has one of the z-values you specified in your switch statement a Toast will be displayed. You were on the right track by adding a boolean value to track if the message had already displayed, but the while loop you have will never execute because isToasted is set to false .

Actually, you don't even need a loop. All you have to do is check if the z-value is between a range of two values. If so, you set the boolean to true. If not, you check if the boolean is true and the z-value is is above or below the range. Then you can set the Toast accordingly, and set the boolean to false so that the message will not display a second time.

private boolean isReset = true;
private float mMaxValue = 7;
private float mDeadZone = 5;

@Override
public void onSensorChanged(SensorEvent event) {
    float value = event.values[2];

    if(value >= mDeadZone || value <= -mDeadZone) {
        if(isReset && value <= -mMaxValue) {
            Toast.makeText(find_word2.this, "correct", Toast.LENGTH_SHORT).show();
            isReset = false;
        } else if(isReset && value >= mMaxValue) {
            Toast.makeText(find_word2.this, "wrong", Toast.LENGTH_SHORT).show();
            isReset = false;
        }
    } else {
        isReset = true;
    }
}

You could also create a "dead zone" by making the range in the outer if statement lower than the maximum value. This would ensure that the user would have to reset the device closer to zero before the Toast could be displayed again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM