英文:
How to pass raw resource id data from activity to service?
问题
我被要求使用Android核心组件仅显示歌曲列表,播放、暂停和停止功能。已成功显示歌曲列表,实现了播放/暂停/停止功能,但问题是只能播放硬编码的音乐文件。
这是我的Service类中的onCreate函数:
override fun onCreate() {
super.onCreate()
mediaPlayer = MediaPlayer.create(this,R.raw.sampl)
mediaPlayer.setOnCompletionListener {
stopSelf()
}
}
基本上,我的目标是能够从用户在片段中选择的raw文件夹中更改R.raw.sampl。
这是我在Fragment中播放音乐的方式:
binding.btnPlay.setOnClickListener {
val intent = Intent(requireContext(), MusicService::class.java)
intent.action = MusicService.ACTION_PLAY
requireActivity().startService(intent)
}
英文:
I was asked to display list of songs, playing, pausing, and stopping only using Android core components.
I've managed to display songs list. Also I have implemented play/pause/stop functionality but the problem is that I can only play hardcoded music files.
This is my onCreate function from the Service class:
override fun onCreate() {
super.onCreate()
mediaPlayer = MediaPlayer.create(this,R.raw.sampl)
mediaPlayer.setOnCompletionListener {
stopSelf()
}
}
Basically, my goal is to be able to change that R.raw.sampl with any other file from my raw folder that user chooses from the fragment.
This is how I am playing music in Fragment
binding.btnPlay.setOnClickListener {
val intent = Intent(requireContext(), MusicService::class.java)
intent.action = MusicService.ACTION_PLAY
requireActivity().startService(intent)
}
答案1
得分: 1
private fun listRaw() {
val fields: Array
for (count in fields.indices) {
val resourceID = fields[count].getInt(fields[count])
}
}
以上代码可用于列出来自raw文件夹的所有文件,并使用资源ID在媒体播放器内播放它们。
mediaPlayer = MediaPlayer.create(this, resourceID)
resourceID将与R.raw.sampl
相同
对于Activity到Service的通信,建议使用Binder。观看此视频以更好地理解服务。
MyService类
class MyService : Service() {
private val binder = MyServiceBinder()
override fun onBind(intent: Intent): IBinder {
return binder
}
fun playMusic(ab: Int) {
val mediaPlayer = MediaPlayer.create(this, ab)
mediaPlayer.start()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_STICKY
}
inner class MyServiceBinder : Binder() {
fun getService() = this@MyService
}
}
在活动中
private lateinit var myService: MyService
private val connection = object : ServiceConnection {
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
val binder = p1 as MyService.MyServiceBinder
myService = binder.getService()
}
override fun onServiceDisconnected(p0: ComponentName?) {
}
}
override fun onStart() {
super.onStart()
Intent(this, MyService::class.java).also {
bindService(it, connection, Context.BIND_AUTO_CREATE)
startService(it)
}
}
override fun onStop() {
super.onStop()
unbindService(connection)
}
在按钮点击或任何需要播放音乐的地方。请使用resourceID而不是R.raw.ab
if (::myService.isInitialized) {
myService.playMusic(R.raw.ab)
}
英文:
private fun listRaw() {
val fields: Array<Field> = R.raw::class.java.fields
for (count in fields.indices) {
val resourceID = fields[count].getInt(fields[count])
}
}
The above code can be used to list all the files from the raw folder and use the resource id to play them inside the media player.
mediaPlayer = MediaPlayer.create(this,resourceID)
resourceID will be same as R.raw.sampl
For Activity to Service communication, it is advised to use Binder.
Watch this video for getting a better understanding on service.
MyService class
class MyService : Service() {
private val binder = MyServiceBinder()
override fun onBind(intent: Intent): IBinder {
return binder
}
fun playMusic(ab: Int) {
val mediaPlayer = MediaPlayer.create(this,ab)
mediaPlayer.start()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_STICKY
}
inner class MyServiceBinder : Binder(){
fun getService() = this@MyService
}
}
And in the activity
private lateinit var myService: MyService
private val connection = object : ServiceConnection{
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
val binder = p1 as MyService.MyServiceBinder
myService = binder.getService()
}
override fun onServiceDisconnected(p0: ComponentName?) {
}
}
override fun onStart() {
super.onStart()
Intent(this,MyService::class.java).also{
bindService(it,connection,Context.BIND_AUTO_CREATE)
startService(it)
}
}
override fun onStop() {
super.onStop()
unbindService(connection)
}
And on button click or whenever you want to play music. Instead of R.raw.ab use the resourceID
if (::myService.isInitialized) {
myService.playMusic(R.raw.ab)
}
答案2
得分: 0
你可以通过意图传递原始资源 ID 给你的服务:
binding.btnPlay.setOnClickListener {
val intent = Intent(requireContext(), MusicService::class.java)
intent.putExtra("playSong", R.raw.sampl)
intent.action = MusicService.ACTION_PLAY
requireActivity().startService(intent)
}
然后,在服务中获取你的资源 ID:
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
if (intent != null && intent.extras != null) {
val songResId = intent.getIntExtra("playSong", -1)
if (songResId != -1) {
// 播放歌曲
}
}
}
英文:
You can pass your raw resource id to your service via intent:
binding.btnPlay.setOnClickListener {
val intent = Intent(requireContext(), MusicService::class.java)
intent.putExtra("playSong", R.raw.sampl)
intent.action = MusicService.ACTION_PLAY
requireActivity().startService(intent)
}
Then, get your resource id in the service:
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
if (intent != null && intent.extras != null) {
val songResId = intent.getIntExtra("playSong", -1)
if (songResId != -1) {
//play song
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论