Android: OnClick воспроизводит случайный .mp3 из файла /res/raw

Я новичок в разработке приложений для Android и пытаюсь воспроизвести случайный .mp3 из папки /res/raw.

ИСПРАВЛЕНО У меня это пока есть, но я столкнулся с FileNotFoundException.

ИСПРАВЛЕНО Воспроизведение случайного звука только при первом нажатии, после этого тот же звук, если повторно не открыть приложение.

НОВАЯ ПРОБЛЕМА Теперь воспроизводит случайные звуки, но когда я нажимаю кнопку несколько раз, звуки начинают воспроизводиться одновременно, и в журналах по-прежнему появляется сообщение «start() mUri is null».

ОБНОВЛЕННЫЙ КОД

MediaPlayer player;
int soundIndex;
AssetFileDescriptor descriptor;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

}


/**
 * gets a random index from an array of sounds
 * 
 * @return
 */
public int getRandomSoundIndex(){

    int soundIndex;
    int[] sound = SOUNDZ;

    Random random = new Random();
    soundIndex = random.nextInt(sound.length);

    return sound[soundIndex];
}

/**
 * Plays that random sound on button click
 * @param button
 */
public void playRandomSound(View button){

    //where button is physically located
    button = (Button) findViewById(R.id.button1);

    //get random sound index
    soundIndex = getRandomSoundIndex();

    //make media player
    player = MediaPlayer.create(this, soundIndex);

    //play sound
    player.start();

}

Вот журнал:


09-21 17:42:32.528: D/MediaPlayer(4282): start() mUri имеет значение null


person LenaSanch    schedule 21.09.2013    source источник


Ответы (1)


У вас есть несколько проблем здесь.

Во-первых, вызов toString() для Field даст вам строковое представление экземпляра объекта, например "public static final int com.lena.button.R$raw.laptopkeyboard1", что не очень полезно. Предположительно, вы хотите getInt().

Во-вторых, необработанный ресурс не является активом, поэтому вы не используете openFd(). Вместо этого используйте статический метод create() для создания экземпляра MediaPlayer, передав int, полученный от getInt() на Field.

В-третьих, отражение медленное. Пожалуйста, не делайте этого более одного раза. Используйте R.raw.class.getFields() один раз для кэширования результатов. Или, что еще лучше, подумайте о том, чтобы вообще не использовать отражение, а вместо этого использовать собственный литерал Java int[]:

static int[] SOUNDZ={R.raw.boom, R.raw.chaka, R.raw.laka};

(подставляя свои звуковые ресурсы, разумеется)

person CommonsWare    schedule 21.09.2013
comment
Спасибо! Я заставил его воспроизводить случайный звук при первом нажатии, используя мой собственный литерал Java int[]. Теперь, когда я снова нажимаю кнопку, он воспроизводит тот же звук. Есть ли способ сбросить нажатие кнопки? - person LenaSanch; 22.09.2013
comment
В логах написано MediaPlayer(4282): start() mUri is null Что это значит? - person LenaSanch; 22.09.2013
comment
@LenaSanch: Есть ли способ сбросить нажатие кнопки? -- create() новый MediaPlayer, насколько я знаю. - person CommonsWare; 22.09.2013