前提・実現したいこと
デバイス内の音楽をシャッフル再生するアプリをMediaPlayerを用いて作りたいです。
現時点では、以下のような機能を持っています。
- 最初に再生ボタン(playButton)を押すと、デバイス内のランダムな音楽が再生され、その後は一時停止、再生ボタンとして機能する。
- 音楽名を表示するTextView(musicName)、再生位置を表示するSeekBar(positionBar)がある。
発生している問題・エラーメッセージ
音楽は再生できるのですが、2曲目以降の再生が上手くいきません。
曲が終わったら、ランダムに音楽を再生する、これを無限に繰り返すようにしたいです。
該当のソースコード
MainActivity.kt
kotlin
1package com.example.randommusicplayer 2 3import android.annotation.SuppressLint 4import android.media.MediaPlayer 5import androidx.appcompat.app.AppCompatActivity 6import android.os.Bundle 7import android.os.Handler 8import android.os.Message 9import kotlinx.android.synthetic.main.activity_main.* 10import android.widget.SeekBar 11 12 13 14class MainActivity : AppCompatActivity() { 15 16 private var totalTime: Int? = null 17 18 override fun onCreate(savedInstanceState: Bundle?) { 19 super.onCreate(savedInstanceState) 20 setContentView(R.layout.activity_main) 21 22 // ランダムに音楽情報を取得 23 val mItems = MusicItem.getItems(applicationContext) 24 val musicData = mItems.random() 25 26 // Media Playerの初期化 27 val mp = MediaPlayer.create(this, musicData.uri) 28 mp.isLooping = false 29 mp.seekTo(0) 30 totalTime = mp.duration 31 32 // 曲名の設定 33 musicName.text = musicData.title 34 35 // 再生位置 36 positionBar.max = totalTime as Int 37 positionBar.setOnSeekBarChangeListener( 38 object : SeekBar.OnSeekBarChangeListener { 39 override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { 40 if (fromUser) { 41 mp.seekTo(progress) 42 positionBar.progress = progress 43 } 44 } 45 46 override fun onStartTrackingTouch(seekBar: SeekBar) { 47 48 } 49 50 override fun onStopTrackingTouch(seekBar: SeekBar) { 51 52 } 53 } 54 ) 55 56 // Thread (positionBar、経過時間ラベル、残り時間ラベルを更新する) 57 Thread(Runnable { 58 while (mp != null) { 59 try { 60 val msg = Message() 61 msg.what = mp.currentPosition 62 handler.sendMessage(msg) 63 Thread.sleep(100) 64 } catch (e: InterruptedException) { 65 } 66 } 67 }).start() 68 69 // 曲が終了したら 70 mp.setOnCompletionListener { 71 playButton.setImageResource(R.drawable.ic_play_arrow_white_24dp) 72 } 73 74 playButton.setOnClickListener { 75 when(mp.isPlaying){ 76 // 再生中 77 true -> { 78 mp.pause() 79 playButton.setImageResource(R.drawable.ic_play_arrow_white_24dp) 80 81 } 82 // 停止中 83 false -> { 84 mp.start() 85 playButton.setImageResource(R.drawable.ic_pause_white_24dp) 86 } 87 } 88 } 89 } 90 91 private val handler = @SuppressLint("HandlerLeak") 92 object : Handler() { 93 override fun handleMessage(msg: Message) { 94 val currentPosition: Int = msg.what 95 96 // 再生位置を更新 97 positionBar.progress = currentPosition 98 99 // 経過時間ラベルを更新 100 val elapsedTime = createTimeLabel(currentPosition) 101 elapsedTimeLabel.text = elapsedTime 102 103 // 残り時間ラベルを更新 104 val remainingTime = createTimeLabel(totalTime!!.minus(currentPosition)) 105 remainingTimeLabel.text = "- $remainingTime" 106 } 107 } 108 109 fun createTimeLabel(time: Int): String { 110 var timeLabel: String 111 val min = time / 1000 / 60 112 val sec = time / 1000 % 60 113 114 timeLabel = "$min:" 115 if(sec < 10) timeLabel += "0" 116 timeLabel += sec.toString() 117 118 return timeLabel 119 } 120 121}
MusicItemは、デバイス内の音楽情報をリストにするためのクラスでここのサンプルコードをお借りしました。
試したこと
setOnCompletionListener内で、
// ランダムに音楽情報を取得 mItems = MusicItem.getItems(applicationContext) musicData = mItems.random() mp = MediaPlayer.create(this, musicData.uri) mp.seekTo(0) totalTime = mp.duration // 曲名の設定 musicName.text = musicData.title
このように書きましたが、2曲目しか再生されませんでした。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/07/10 14:30