Почему звуковой сигнал вызывает сбой приложения?

Я пытаюсь сделать индикатор уровня, который издает более быстрый звуковой сигнал, когда телефон достигает горизонтального положения (используя акселерометр), звуковой сигнал воспроизводится после прикосновения к экрану и прекращается, если экран коснулся снова. Итак, я сделал следующий код, и проблема заключается в том, что, поскольку я добавил часть звукового сигнала (с функцией MyRunnable, вызываемой в событии onTouch), мое приложение падает через несколько секунд (оно отлично работает в течение нескольких секунд, и у меня есть никаких сообщений об ошибках после сборки). Я действительно понятия не имею, в чем может быть проблема. Я застрял здесь и мне нужна помощь, спасибо!

открытый класс MainActivity расширяет AppCompatActivity, реализует 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;
}

}

Вот информация Logcat, кажется, она показывает некоторые проблемы, но я не знаю, что это значит. информация logcat


person Community    schedule 15.03.2018    source источник
comment
Пожалуйста, опубликуйте вывод Logcat (детали исключения).   -  person Maciej Białorucki    schedule 15.03.2018
comment
Я не знаю, что такое вывод Logcate? Это Logcat из View -> ToolWindows -> logcat?   -  person    schedule 15.03.2018
comment
Здесь у вас есть информация об использовании logcat с командной строкой developer.android.com/studio/ command-line/logcat.html и здесь, в Android Studio developer. android.com/studio/debug/am-logcat.html   -  person Maciej Białorucki    schedule 15.03.2018
comment
Поэтому я добавляю изображение информации logcat (ошибки и предупреждения), но не очень понимаю, что это значит   -  person    schedule 15.03.2018


Ответы (2)


Я нашел ответ, который работает для меня, в ToneGenerator аварийно завершает работу в Android 6.0

«Речь шла только об освобождении созданных объектов ToneGenerator, потому что быстрое создание объектов ToneGenerator без их освобождения приведет к сбою приложения».

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

Я добавляю toneGen1.release(); и теперь работает нормально.

кредиты Махмуду Фарахату.

person Community    schedule 15.03.2018

С семафором (tonebusy), который кажется работающим (KOTLIN):

var tonebusy : Boolean = false

fun beep(i : Int) {

    if (tonebusy) {
        return
    }
    else 
    {
      tonebusy = true
      val toneGen1 = ToneGenerator(AudioManager.STREAM_MUSIC, 100)
      toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP, i)
      toneGen1.release();
    }
    tonebusy = false

}
person ccour    schedule 08.04.2021