Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

17.2. bindService

		
<!-- 在AndroidManifest.xml中添加服务声明 -->
<application
    android:name=".MyApplication"
    ...>
    
    <service
        android:name=".OpusBackgroundService"
        android:foregroundServiceType="mediaPlayback"
        android:exported="false" />
        
    <!-- 添加音频焦点权限 -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
</application>

		
		
		
import android.app.Application

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // 初始化并绑定服务(实际项目中可在需要时再绑定)
        OpusPlayerManager.bindService(this)
    }

    override fun onTerminate() {
        super.onTerminate()
        // 解绑服务
        OpusPlayerManager.unbindService(this)
    }
}

		
		
		
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.upstream.ByteArrayDataSource
import com.google.android.exoplayer2.upstream.DataSource

class OpusBackgroundService : Service() {
    private val binder = LocalBinder()
    private lateinit var exoPlayer: ExoPlayer

    // 本地Binder,用于Activity绑定服务
    inner class LocalBinder : Binder() {
        val service: OpusBackgroundService
            get() = this@OpusBackgroundService
    }

    override fun onCreate() {
        super.onCreate()
        // 初始化ExoPlayer
        exoPlayer = ExoPlayer.Builder(this).build()
    }

    // 播放Opus字节流
    fun playOpusStream(opusBytes: ByteArray) {
        // 创建内存数据源
        val byteArrayDataSource = ByteArrayDataSource(opusBytes)
        val dataSourceFactory = DataSource.Factory { byteArrayDataSource }

        // 创建媒体源
        val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
            .createMediaSource(MediaItem.fromUri("memory://opus-stream"))

        // 准备并播放
        exoPlayer.setMediaSource(mediaSource)
        exoPlayer.prepare()
        exoPlayer.playWhenReady = true
    }

    // 暂停播放
    fun pause() {
        exoPlayer.playWhenReady = false
    }

    // 继续播放
    fun resume() {
        exoPlayer.playWhenReady = true
    }

    // 停止播放并释放资源
    private fun stopAndRelease() {
        exoPlayer.stop()
        exoPlayer.release()
    }

    override fun onBind(intent: Intent): IBinder = binder

    override fun onDestroy() {
        super.onDestroy()
        stopAndRelease()
    }
}

		
		
		
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder

object OpusPlayerManager {
    private var service: OpusBackgroundService? = null
    private var isBound = false

    // 绑定服务
    fun bindService(context: Context) {
        val intent = Intent(context, OpusBackgroundService::class.java)
        context.bindService(intent, connection, Context.BIND_AUTO_CREATE)
    }

    // 解绑服务
    fun unbindService(context: Context) {
        if (isBound) {
            context.unbindService(connection)
            isBound = false
            service = null
        }
    }

    // 播放Opus字节流
    fun playOpus(opusBytes: ByteArray) {
        service?.playOpusStream(opusBytes)
    }

    // 暂停播放
    fun pause() {
        service?.pause()
    }

    // 服务连接回调
    private val connection = object : ServiceConnection {
        override fun onServiceConnected(className: ComponentName, serviceBinder: IBinder) {
            val binder = serviceBinder as OpusBackgroundService.LocalBinder
            service = binder.service
            isBound = true
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            isBound = false
        }
    }
}