MediaStore.Audio.Radio示例缺失及安卓应用离线电台播放需求
我完全懂你找不到安卓Radio相关资源的郁闷——毕竟这个功能从API Level 21才新增,而且日常用的人不多,网上资料确实稀缺。下面直接给你MediaStore.Audio.Radio的实用示例,以及离线电台播放的实现思路,帮你在自己的应用里搞定需求:
一、MediaStore.Audio.Radio 基础操作示例
首先,你需要先申请必要的权限:
READ_EXTERNAL_STORAGE(读取系统电台数据)INTERNET(在线播放电台)RECORD_AUDIO&WRITE_EXTERNAL_STORAGE(离线录制用,高版本Android需要适配MANAGE_EXTERNAL_STORAGE)
1. 获取系统电台列表
// 查询系统中的电台信息 val projection = arrayOf( MediaStore.Audio.Radio._ID, MediaStore.Audio.Radio.NAME, MediaStore.Audio.Radio.STREAM_URI, MediaStore.Audio.Radio.FREQUENCY ) val cursor = contentResolver.query( MediaStore.Audio.Radio.EXTERNAL_CONTENT_URI, projection, null, null, "${MediaStore.Audio.Radio.NAME} ASC" ) cursor?.use { while (it.moveToNext()) { val id = it.getLong(it.getColumnIndexOrThrow(MediaStore.Audio.Radio._ID)) val name = it.getString(it.getColumnIndexOrThrow(MediaStore.Audio.Radio.NAME)) val streamUri = it.getString(it.getColumnIndexOrThrow(MediaStore.Audio.Radio.STREAM_URI)) val frequency = it.getInt(it.getColumnIndexOrThrow(MediaStore.Audio.Radio.FREQUENCY)) // 这里可以把电台信息存到自定义的数据类里,供后续使用 println("电台:$name,频率:$frequency,流地址:$streamUri") } }
2. 在线播放电台
用MediaPlayer来播放电台流:
private var mediaPlayer: MediaPlayer? = null fun playRadio(streamUri: String) { mediaPlayer?.release() mediaPlayer = MediaPlayer().apply { setAudioAttributes( AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ) setDataSource(streamUri) prepareAsync() setOnPreparedListener { start() } setOnErrorListener { _, what, extra -> println("播放出错:what=$what, extra=$extra") true } } } // 记得在页面销毁时释放资源 override fun onDestroy() { super.onDestroy() mediaPlayer?.release() mediaPlayer = null }
二、离线电台播放实现思路
要实现离线播放,核心是录制电台流到本地文件,之后播放本地文件即可:
1. 录制电台流
可以直接通过网络请求读取流并写入文件(比MediaRecorder更灵活):
fun recordRadioToFile(streamUri: String, outputPath: String) { CoroutineScope(Dispatchers.IO).launch { try { val url = URL(streamUri) val connection = url.openConnection() as HttpURLConnection connection.doInput = true connection.connect() val inputStream = connection.inputStream val outputStream = FileOutputStream(outputPath) val buffer = ByteArray(4096) var bytesRead: Int while (inputStream.read(buffer).also { bytesRead = it } != -1) { outputStream.write(buffer, 0, bytesRead) } inputStream.close() outputStream.close() connection.disconnect() // 录制完成,通知主线程更新UI withContext(Dispatchers.Main) { println("录制完成,文件路径:$outputPath") } } catch (e: Exception) { e.printStackTrace() withContext(Dispatchers.Main) { println("录制失败:${e.message}") } } } }
2. 播放本地录制的电台文件
直接用MediaPlayer播放本地文件路径即可,和播放普通音频文件一样:
fun playOfflineRadio(localFilePath: String) { mediaPlayer?.release() mediaPlayer = MediaPlayer().apply { setAudioAttributes( AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ) setDataSource(localFilePath) prepareAsync() setOnPreparedListener { start() } } }
注意事项
- 高版本Android(13+)需要单独申请
POST_NOTIFICATIONS权限,否则后台播放可能被限制 - 录制的文件格式建议用
.mp3或者.m4a,保证兼容性 - 处理电台流时要注意网络异常,比如断网时要及时停止录制或播放
内容的提问来源于stack exchange,提问作者Sagar Adhikari
相关产品推荐
相关产品推荐

