用Kotlin写一个音乐播放器

添加依赖 implementation "org.jetbrains.anko:anko:0.10.8"
class home_frame : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val inflate = LayoutInflater.from(context).inflate(R.layout.home_frame, null)
        val recy = inflate.findViewById<RecyclerView>(R.id.recy)
        var resolver = context!!.contentResolver
        //开启子线程进行处理
        //把RecyclerView作为参数进行传入
        MediaTask(recy, context!!).execute(resolver)
        return inflate
    }


    class MediaTask(recy: RecyclerView, context: Context) : AsyncTask<ContentResolver, Int, Cursor>() {

        val rv_container = recy
        val context = context
        //子线程
        override fun doInBackground(vararg params: ContentResolver?): Cursor {
            var resolver = params[0]
            var cursor = resolver!!.query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                arrayOf(
                    MediaStore.Audio.Media.DATA,
                    MediaStore.Audio.Media.DISPLAY_NAME,
                    MediaStore.Audio.Media.SIZE,
                    MediaStore.Audio.Media.ARTIST
                ), null, null, null
            )
            return cursor
        }

        override fun onPostExecute(cursor: Cursor?) {
            super.onPostExecute(cursor)

            cursor!!.moveToPosition(-1)
            var musicList = ArrayList<MusicBean>()
            //把查询完毕的数据放入集合
            while (cursor!!.moveToNext()) {
                    var data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))//播放Uri
                    var displayName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME))//默认名称
                    var size = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE))//大小
                    var artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST))//歌手
                    //把内容条目进行填充
                musicList.add(MusicBean(data, displayName, size, artist))

            }

            rv_container.setLayoutManager(LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false))
            var musicAdapter = MusicAdapter(R.layout.recyclerview_music_item, musicList)
            rv_container.setAdapter(musicAdapter)
            //条目点击事件,跳转音乐播放界面
            musicAdapter.setOnItemClickListener { adapter, view, position ->
                context.startActivity<AudioActivity>(
                    "musicList" to musicList,
                    "position" to position
                )
            }

        }


    }
}

bean类

data class MusicBean(var data: String, var displayName: String, var size: String, var artist: String):Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString(),
        parcel.readString(),
        parcel.readString(),
        parcel.readString()
    ) {
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(data)
        parcel.writeString(displayName)
        parcel.writeString(size)
        parcel.writeString(artist)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<MusicBean> {
        override fun createFromParcel(parcel: Parcel): MusicBean {
            return MusicBean(parcel)
        }

        override fun newArray(size: Int): Array<MusicBean?> {
            return arrayOfNulls(size)
        }
    }
}

适配器

class MusicAdapter(layoutResId: Int, data: MutableList<MusicBean>?) :
    BaseQuickAdapter<MusicBean, BaseViewHolder>(layoutResId, data) {

    override fun convert(helper: BaseViewHolder?, item: MusicBean?) {
        helper!!.setText(R.id.tv_music_item_right, item!!.displayName)
    }
}

AudioActivity

class AudioActivity : AppCompatActivity() {
    val musicService = MusicService()
    //连接对象
    val connection by lazy { MyConnection() }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_audio)
        //音乐条目的集合
        var musicList = intent.getParcelableArrayListExtra<MusicBean>("musicList")
        var position = intent.getIntExtra("position", -1)
        //获取Service
        //var musicService = MusicService()
        //Intent值传入到Service中
        var intent = Intent(this, musicService.javaClass)
        intent.putExtra("musicList", musicList)
        intent.putExtra("position", position)
        //开启服务
        this.startService(intent)
        //绑定
        this.bindService(intent, connection, Context.BIND_AUTO_CREATE)


        //MediaPlayer
        /* var mediaPlayer = MediaPlayer()
         //准备
         mediaPlayer.setOnPreparedListener {
             mediaPlayer.start()
         }
         //关键方法:需要设置播放的路径Uri
         mediaPlayer.setDataSource(musicList.get(position).data)
         mediaPlayer.prepareAsync()*/
    }
    class MyConnection : ServiceConnection {
        /**
         * 服务断开时
         */
        override fun onServiceDisconnected(name: ComponentName?) {

        }

        /**
         * 服务连接时
         */
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {

        }

    }
}

musicService

class MusicService:Service() {
    //音乐播放器
    var mediaPlayer: MediaPlayer? = null
    //音乐集合
    var musicList: ArrayList<MusicBean>? = null;
    //位置
    var position: Int = 0

    //加载
    var binder: MusicService.InnerBinder = InnerBinder()

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        //对音乐集合和位置的接收
        musicList = intent?.getParcelableArrayListExtra<MusicBean>("musicList")
        position = intent?.getIntExtra("position", -1)!!
        //播放
        binder.playItem()
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onBind(intent: Intent?): IBinder {
        return binder
    }

    /**
     * 最核心的部分
     */
    inner class InnerBinder : Binder(), MediaPlayer.OnPreparedListener {
        override fun onPrepared(mp: MediaPlayer?) {
            //准备好做什么,由用户决定
            mediaPlayer?.start()
        }

        //播放条目音乐
        fun playItem() {
            //获取MediaPlayer
            mediaPlayer = MediaPlayer()
            mediaPlayer!!.setOnPreparedListener(this)
            //获取播放路径
            mediaPlayer!!.setDataSource(musicList?.get(position)!!.data)
            mediaPlayer?.prepareAsync()
        }
    }
}
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是一个简单的音乐播放器Kotlin代码: ```kotlin import android.media.MediaPlayer import android.os.Bundle import android.os.Handler import android.support.v7.app.AppCompatActivity import android.widget.Button import android.widget.SeekBar import android.widget.TextView import java.util.concurrent.TimeUnit class MainActivity : AppCompatActivity() { private lateinit var mediaPlayer: MediaPlayer private lateinit var playButton: Button private lateinit var seekBar: SeekBar private lateinit var currentPositionTextView: TextView private lateinit var durationTextView: TextView private lateinit var handler: Handler private var isPlaying = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mediaPlayer = MediaPlayer.create(this, R.raw.song) playButton = findViewById(R.id.playButton) seekBar = findViewById(R.id.seekBar) currentPositionTextView = findViewById(R.id.currentPositionTextView) durationTextView = findViewById(R.id.durationTextView) handler = Handler() // 设置seekBar的最大值为音频的总长度 seekBar.max = mediaPlayer.duration // 更新seekBar和当前位置文本的UI updateUI() // 播放按钮点击事件 playButton.setOnClickListener { if (isPlaying) { mediaPlayer.pause() playButton.text = "播放" } else { mediaPlayer.start() playButton.text = "暂停" } isPlaying = !isPlaying } // seekBar滑动事件 seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { if (fromUser) { mediaPlayer.seekTo(progress) updateUI() } } override fun onStartTrackingTouch(seekBar: SeekBar?) {} override fun onStopTrackingTouch(seekBar: SeekBar?) {} }) } // 更新UI的方法 private fun updateUI() { handler.postDelayed({ // 使用handler每隔1秒更新UI val currentPosition = mediaPlayer.currentPosition seekBar.progress = currentPosition currentPositionTextView.text = formatTime(currentPosition) durationTextView.text = formatTime(mediaPlayer.duration) updateUI() }, 1000) } // 将时间格式化为"mm:ss"的方法 private fun formatTime(time: Int): String { val minutes = TimeUnit.MILLISECONDS.toMinutes(time.toLong()) val seconds = TimeUnit.MILLISECONDS.toSeconds(time.toLong()) - TimeUnit.MINUTES.toSeconds(minutes) return String.format("%02d:%02d", minutes, seconds) } // 在activity销毁时释放MediaPlayer资源 override fun onDestroy() { super.onDestroy() mediaPlayer.release() } } ``` 这个示例代码中,我们使用了MediaPlayer来播放本地的一个音频文件,使用SeekBar来控制播放进度和展示播放进度,使用Handler每隔1秒更新UI,使用TimeUnit将毫秒转换为分钟和秒钟,并格式化时间为"mm:ss"格式。同时,在activity销毁时,我们也释放了MediaPlayer资源。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值