MediaPlayerをカスタムViewにした
MediaPlayerとか使うたびにロジック組むのがめんどくさいので、Viewにまとめた
PlayerView
MediaPlayerのカスタムビュー
1曲しか再生できない
PlayerListener:MediaPlayer.xxListenerのデリゲート
早送り、巻き戻しは5秒
SeekRunner:SeekBarのスケジューラ。誰かがAndroidでTimerは使うなとかいってたのでExecuterにしてみた
open(File file):引数のFileを再生する使う
MediaPlayerAvtivity
PlayerViewを使う人
ソース
PlayerView
public class PlayerView extends FrameLayout implements OnBufferingUpdateListener, OnErrorListener, OnCompletionListener, OnPreparedListener, OnClickListener { private static final String TAG = PlayerView.class.getName(); public static final int STATUS_PALYER_NO_START = 0; public static final int STATUS_PALYER_PREPARED = 1; public static final int STATUS_PALYER_PLAYED = 2; private static final int STATUS_PALYER_STOP = 3; private static final int ACCELERATION_VALUE = 5000; private static final int THREAD_RUNNING_INTERVAL = 500; private AtomicInteger statusPlayer = new AtomicInteger(); private MediaPlayer player; private PlayerListener listener; private ImageButton buttonPlay; private ImageButton buttonRew; private ImageButton buttonFF; private SeekBar seekbar; private View rootView; private File streamFile; private int duration; ScheduledExecutorService scheduledEx; private FileInputStream fileInputStream; public MediaPlayer getPlayer() { return player; } public SeekBar getSeekbar() { return seekbar; } public interface PlayerListener { public void onPrepared(); public void onCompletion(); public boolean onError(int what, int extra); public void onBufferingUpdate(int percent); } public PlayerView(Context context) { super(context); } public PlayerView(Context context, AttributeSet attrs) { super(context, attrs); statusPlayer.set(STATUS_PALYER_NO_START); scheduledEx = Executors.newSingleThreadScheduledExecutor(); player = new MediaPlayer(); initView(); } private void initView() { LayoutInflater inflater = LayoutInflater.from(this.getContext()); rootView = (LinearLayout) inflater.inflate(R.layout.player, null); addView(rootView); buttonPlay = (ImageButton) rootView.findViewById(R.id.button_play); buttonPlay.setOnClickListener(this); buttonRew = (ImageButton) rootView.findViewById(R.id.button_rew); buttonRew.setOnClickListener(this); buttonFF = (ImageButton) rootView.findViewById(R.id.button_ff); buttonFF.setOnClickListener(this); seekbar = (SeekBar)findViewById(R.id.seekBar1); seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { player.seekTo(progress); } } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_play: play(); break; case R.id.button_ff: ff(); break; case R.id.button_rew: rew(); break; } } private void rew() { int current = player.getCurrentPosition(); player.seekTo(current - ACCELERATION_VALUE); } private void play() { if (player != null) { if (player.isPlaying()) { player.pause(); buttonPlay.setImageResource(android.R.drawable.ic_media_play); } else { buttonPlay.setImageResource(android.R.drawable.ic_media_pause); player.start(); } } if(statusPlayer.get() == STATUS_PALYER_PREPARED){ scheduledEx.scheduleAtFixedRate(new SeekRunner("seek task"), 0, THREAD_RUNNING_INTERVAL, TimeUnit.MILLISECONDS); statusPlayer.set(STATUS_PALYER_PLAYED); } } public AtomicInteger getStatusPlayer() { return statusPlayer; } private void ff() { int current = player.getCurrentPosition(); player.seekTo(current + ACCELERATION_VALUE); } public void setListener(PlayerListener listener) { this.listener = listener; } @Override public void onPrepared(MediaPlayer mp) { listener.onPrepared(); } @Override public void onCompletion(MediaPlayer mp) { listener.onCompletion(); } @Override public boolean onError(MediaPlayer mp, int what, int extra) { listener.onError(what, extra); return false; } @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { seekbar.setSecondaryProgress(percent); listener.onBufferingUpdate(percent); } public void open(File file) { streamFile = file; try { fileInputStream = new FileInputStream(streamFile); player.setDataSource(fileInputStream.getFD()); player.prepare(); duration = player.getDuration(); seekbar.setMax(duration); statusPlayer.set(STATUS_PALYER_PREPARED); } catch (Exception e) { _L.e(TAG, "open", e); } } public boolean isPlaying(){ if(player == null){ return false; } return player.isPlaying(); } class SeekRunner implements Runnable{ private String name; public SeekRunner(String name) { this.name = name; } @Override public void run() { int currentPosition = player.getCurrentPosition(); seekbar.setProgress(currentPosition); } } }
player.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <SeekBar android:id="@+id/seekBar1" android:layout_height="wrap_content" android:layout_width="fill_parent"></SeekBar> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/linearLayout1"> <ImageButton android:id="@+id/button_rew" style="@android:style/MediaButton.Previous" /> <ImageButton android:id="@+id/button_play" style="@android:style/MediaButton.Play" /> <ImageButton android:id="@+id/button_ff" style="@android:style/MediaButton.Next" /> </LinearLayout> </LinearLayout>
MediaPlayerAvtivity
public class MediaPlayerAvtivity extends Activity { private File mediaFile; private PlayerView playerView; private TextView textTitle; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); playerView = (PlayerView)findViewById(R.id.player); textTitle = (TextView)findViewById(R.id.text_title); initMediaFile(); playerView.open(mediaFile); } private void initMediaFile(){ Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; String[] projection = { AudioColumns._ID, AudioColumns.TITLE, AudioColumns.ALBUM, AudioColumns.ARTIST, AudioColumns.DATA }; String sortOrder = MediaColumns.DATE_ADDED + " DESC"; Cursor cursor = managedQuery(uri, projection, null, null, sortOrder); if (cursor.moveToFirst()) { int idIndex = cursor.getColumnIndex(AudioColumns._ID); int titleIndex = cursor.getColumnIndex(AudioColumns.TITLE); int albumIndex = cursor.getColumnIndex(AudioColumns.ALBUM); int artistIndex = cursor.getColumnIndex(AudioColumns.ARTIST); int dataIndex = cursor.getColumnIndex(AudioColumns.DATA); String sdcardPath = Environment.getExternalStorageDirectory().getPath(); if(sdcardPath != null){ String title = cursor.getString(titleIndex); textTitle.setText(title); String mediaPath = cursor.getString(dataIndex); mediaFile = new File(mediaPath); _L.d(mediaFile.toString()); } } cursor.close(); } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/text_title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <com.hidecheck.mediaplayer.view.PlayerView android:id="@+id/player" android:layout_height="wrap_content" android:layout_width="fill_parent" /> </LinearLayout>