简体   繁体   中英

Android: OnClick play random .mp3 from /res/raw file

I am fairly new to Android Application development, and I'm trying to play a random .mp3 from the /res/raw folder.

FIXED I have this so far, but I came across a FileNotFoundException.

FIXED Only plays a random sound on first click, after that it is the same sound unless reopen the app.

NEW ISSUE Now plays random sounds, but when I click the button multiple times the sounds start playing at the same time and still getting the "start() mUri is null" message in the logs.

UPDATED CODE

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();

}

Here is the log:


09-21 17:42:32.528: D/MediaPlayer(4282): start() mUri is null

You have a few problems here.

First, calling toString() on a Field will give you a string representation of the object instance, such as "public static final int com.lena.button.R$raw.laptopkeyboard1" , which is not very useful. Presumably, you want getInt() .

Second, a raw resource is not an asset, and so you do not use openFd() . Instead, use the static create() method to create your MediaPlayer instance, passing in the int you get from getInt() on your Field .

Third, reflection is slow. Please do not do it more than once. Use R.raw.class.getFields() once , caching the results. Or, better yet, consider not using reflection at all, and instead using your own literal Java int[] :

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

(substituting in your own sound resources, of course)

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