Search code examples
androidcrashhandleraccelerometerontouchlistener

Why the beep sound makes app crashes?


I try to make a level indicator which beeps quicker when the phone reach an horizontal position (using the accelerometer), the beep sound plays after a touch on the screen and stop if screen is touched again. So I made the following code, and the problem I have is that since I've add the "beep" sound part (with MyRunnable function called in the onTouch event), my app crashes after few seconds (it works fine for few second and I have no error messages after the build). I really have no clue on what the problem could be. I'm stuck here and need some help, thanks !

public class MainActivity extends AppCompatActivity implements SensorEventListener, View.OnTouchListener {

Sensor mySensor;
SensorManager SM;

float ANGLEX, ANGLEY, ANGLEZ;
int aX, aY, aZ;
int roundANGLEX, roundANGLEY, roundANGLEZ;
int Xetal, Yetal;
double centre;
int Rcentre;
int Rcentre2;
boolean active;
int test;

int i=0;
private Handler myHandler;

private Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        // Play a periodic beep which accelerates according to Rcentre2

        ToneGenerator toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
        toneGen1.startTone(ToneGenerator.TONE_PROP_BEEP,150);
        myHandler.postDelayed(this,(long) Math.sqrt(Rcentre2*20)+50);
    }
};

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Créée notre Sensor Manager
    SM = (SensorManager) getSystemService(SENSOR_SERVICE);

    //Accéléromètre
    mySensor = SM.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

    //Registre Sensor Listener
    SM.registerListener(this, mySensor, 1000000, 1000000);


    ((ConstraintLayout) findViewById(R.id.layout_main)).setOnTouchListener((View.OnTouchListener) this);
}



@Override
public void onAccuracyChanged(Sensor sensor, int i) {
    //Pas utilisé
}


@Override
public void onSensorChanged(SensorEvent sensorEvent) {

    float z_stable = ((int) ((sensorEvent.values[2]) * 100)) / 100.0f;


    ANGLEX = (float) (((float) (Math.acos(sensorEvent.values[0] / 9.807)) * (180 / Math.PI))); //I get the accelerometer's values
    ANGLEY = (float) (((float) (Math.acos(sensorEvent.values[1] / 9.807)) * (180 / Math.PI)));
    ANGLEZ = (float) (((float) (Math.acos(z_stable / 9.807)) * (180 / Math.PI)));

    roundANGLEX = Math.round(ANGLEX);
    roundANGLEY = Math.round(ANGLEY);
    roundANGLEZ = Math.round(ANGLEZ);

    aX = roundANGLEX;
    aY = roundANGLEY;
    aZ = roundANGLEZ;


    Xetal = aX - 88; //Xetal and Yetal are 0 when phone is on plane surface
    Yetal = aY - 90; //and go from -90 to +90

    centre = Math.sqrt(Xetal * Xetal + Yetal * Yetal); //gives the "distance" from the "center => the smaller centre gets, the closer the phone approach horizontal
    Rcentre = (int) Math.round(centre);
    Rcentre2 = (int) Math.round(centre * 100);
}


public boolean onTouch(View view, MotionEvent motionEvent) {
    if (active == true) {
        active = false;
        myHandler.removeCallbacks(myRunnable);
    }
    else if (active == false) {
        active = true;

            myHandler = new Handler();
            myHandler.postDelayed(myRunnable,0); 

        }
    return false;
}

}

Here are the Logcat infos, it seems to shows some problems but I don't know what that means. logcat information


Solution

  • I found an answer that works for me at ToneGenerator crashes in android 6.0

    "it was just about releasing created objects of ToneGenerator because rapidly creating objects of 'ToneGenerator' without releasing them will cause the application to crash."

            ToneGenerator toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
            toneGen1.startTone(ToneGenerator.TONE_PROP_BEEP,150);
            toneGen1.release();
    

    I add toneGen1.release(); and it now works fine.

    credits to Mahmoud Farahat.