Android MediaPlayer Singleton - PullRequest
       6

Android MediaPlayer Singleton

4 голосов
/ 20 октября 2011

Я прочитал несколько статей здесь, в которых предлагается использовать одноэлементный код, который я прочитал и поместил в звуковую панель, поскольку я хочу использовать одноэлементный код, чтобы разрешить только один экземпляр медиаплеера независимо от того, сколько кликов пользователь определил,

В основном мне нужен только один звук, и если пользователь нажимает другую кнопку во время воспроизведения, он останавливает текущий звук и воспроизводит тот, который был нажат.Я хочу только один экземпляр MediaPlayer, но не понимаю, как его реализовать.

Вот основная идея моего кода:

    package com.example.context;

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;




    import android.app.Activity;
    import android.content.ContentValues;
    import android.content.Intent;
    import android.media.MediaPlayer;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.MediaStore;
    import android.view.ContextMenu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ContextMenu.ContextMenuInfo;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;

    public class main extends Activity implements OnClickListener {

    MediaPlayer player;

    int[] ressound ={R.raw.boomstick, R.raw.chainsaw, R.raw.shebitch, R.raw.byebye,
    R.raw.comegetsome, R.raw.groovy, R.raw.shoelace, R.raw.smart,   R.raw.yeahbaby};//added as needed
    int j=0;
    private static final String TAG = "MyTag";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


     //Coding for all buttons, registers, and Listeners
        Button btn1 = (Button) findViewById(R.id.btn1);
        registerForContextMenu(btn1); 
        btn1.setOnClickListener(this);
        Button btn2 = (Button) findViewById(R.id.btn2);
        registerForContextMenu(btn2);
        btn2.setOnClickListener(this);
        Button btn3 = (Button) findViewById(R.id.btn3);
        registerForContextMenu(btn3);
        btn3.setOnClickListener(this);

    }

     //On click Handlers for multiple buttons 
        public void onClick(View v) {
        switch(v.getId()){
        case R.id.btn1:
        // action to perform on button 1
        j = 0;
        playResource();
        break;
    case R.id.btn2:
        // action to perform on button 1
        j = 1;
        playResource();
        break;
    case R.id.btn3:
        // action to perform on button 1    
        j = 2;
        playResource();
        break;

    }
         public void playResource(int j, int resource) {
    this.j = j;
    if (player != null) {
        if (player.isPlaying())
            player.stop();
        player.reset();
        //from MediaPlayer implementation (link above)
        try {
            AssetFileDescriptor afd = getResources().openRawResourceFd(resource);
            if (afd == null) return;
            player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            afd.close();
            player.prepare();
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        }
    }
    else {
        //player is null
        //it will create new MediaPlayer instance, setDataSource and call prepare
        player = MediaPlayer.create(this, resource);
    }
    //if everything ok play file
    //in case of any error return from method before (catch)
    player.start();
}

Это то, что мне пришлось обновить и изменить мойкод тоже, но это дает мне проблему с передачей функции playresource ().Неужели я передаю это неправильно, если это будет личное сообщение?

Ответы [ 3 ]

4 голосов
/ 20 октября 2011

Вам не нужен синглтон для этого.Что вы делаете, это вызываете метод create каждый раз, когда хотите воспроизвести файл.Это неправильно, потому что у вас уже есть экземпляр MediaPlayer.Проверьте MediaPlayer.create реализации .Я хотел бы сделать так:

  • создать новый метод playResource (int j, int resource)
  • в каждом случае R.id.btnX я бы вызвал метод playResource (X, R.raw.Y) - X и Y зависят от btn

Пример метода playResource:

private static final String TAG = "MyTag";
playResource(int j, int resource) {
    this.j = j;
    if (player != null) {
        if (player.isPlaying())
            player.stop();
        player.reset();
        //from MediaPlayer implementation (link above)
        try {
            AssetFileDescriptor afd = getResources().openRawResourceFd(resource);
            if (afd == null) return null;
            player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            afd.close();
            player.prepare();
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        }
    }
    else {
        //player is null
        //it will create new MediaPlayer instance, setDataSource and call prepare
        player = MediaPlayer.create(this, resource);
    }
    //if everything ok play file
    //in case of any error return from method before (catch)
    player.start();
}

Если вам больше не нужен MediaPlayer, вы должны его освободить.Например, в вызове onPause ():

if (player != null) {
    player.release();
    player = null;
} 

Я не проверял это, поэтому могут быть ошибки.Надеюсь, это поможет.

1 голос
/ 20 октября 2011

Метод getSingletonObject () должен возвращать экземпляр MediaPlayer, созданный с использованием конструктора по умолчанию для MediaPlayer (без указания ресурса).

Вы можете вызвать getSingletonObject () из onCreate () в основном классе и инициализировать игрока с ним.

Позже в onClick () вы должны вызвать player.prepare (), а затем player.setDataSource (), передав ресурс.

Итак, ваш код должен выглядеть примерно так:

   public static MediaPlayer getSingletonObject()
  {
    if (ref == null)
        // it's ok, we can call this constructor
        ref = new MediaPlayer();        
    return ref;
  }

В основном классе, в методе onCreate (),

public void onCreate(Bundle savedInstanceState) {
//....
//....
player=SingletonObject.getSingletonObject();
}

Надеюсь, вы сами сможете выяснить код в onClick (). И не забудьте добавить соответствующие предложения try..catch в метод onClick ().

Надеюсь, это поможет !!

0 голосов
/ 23 июня 2012

Я пытался решить эту проблему для собственного проекта.Я столкнулся с той же проблемой, что при воспроизведении второго воспроизведения произойдет сбой приложения.

Добавление player = new MediaPlayer(); решило проблему (кажется, что медиаплеер не был запущен в блоке try-catch).

См. Код ниже:

    playResource(int j, int resource) {
this.j = j;
if (player != null) {
    if (player.isPlaying())
        player.stop();
    player.reset();

    try {
        player = new MediaPlayer(); //added to the code
        AssetFileDescriptor afd = getResources().openRawResourceFd(resource);
        if (afd == null) return null;
        player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
        afd.close();
        player.prepare();
    } catch (IOException ex) {
        Log.d(TAG, "create failed:", ex);
        // failed: return
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "create failed:", ex);
        // failed: return
    } catch (SecurityException ex) {
        Log.d(TAG, "create failed:", ex);
        // failed: return
    }
}
else {
    //player is null
    //it will create new MediaPlayer instance, setDataSource and call prepare
    player = MediaPlayer.create(this, resource);
}
...