英文:
android MediaSession setActive(false) not work
问题
我使用 MediaSession
来响应耳机媒体按钮,并且希望在活动暂停时停止声音。我还希望在活动暂停时不激活耳机媒体按钮。
根据安卓文档,它说 setActive
方法用于**“设置此会话当前是否处于活动状态并且准备好接收命令”**。但这似乎没有起作用,我仍然可以在活动暂停时使用耳机继续播放音乐。我是否误解了此方法的功能?
我的代码如下:
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class MainActivity : AppCompatActivity() {
private lateinit var mediaSession: MediaSession
private var mediaPlayer: MediaPlayer? = null
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mediaPlayer = MediaPlayer.create(this, R.raw.lapple)
mediaPlayer?.isLooping = true
mediaPlayer?.start()
mediaSession = MediaSession(this, "test_log").apply {
setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS or MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS)
setMediaButtonReceiver(null)
val stateBuilder = PlaybackState.Builder()
.setActions(PlaybackState.ACTION_PLAY or PlaybackState.ACTION_PAUSE or PlaybackState.ACTION_PLAY_PAUSE)
setPlaybackState(stateBuilder.build())
setCallback(object : MediaSession.Callback() {
override fun onPlay() {
Toast.makeText(
this@MainActivity,
"${this@MainActivity.hashCode()}: onPlay",
Toast.LENGTH_SHORT
).show()
mediaPlayer?.start()
}
override fun onPause() {
mediaPlayer?.pause()
Toast.makeText(
this@MainActivity,
"${this@MainActivity.hashCode()}: onPause",
Toast.LENGTH_SHORT
).show()
}
})
}
mediaSession.isActive = true
}
override fun onPause() {
super.onPause()
mediaSession.isActive = false
mediaPlayer?.pause()
}
override fun onResume() {
super.onResume()
mediaSession.isActive = true
mediaPlayer?.start()
}
override fun onDestroy() {
mediaPlayer?.release()
super.onDestroy()
}
fun newActivity(view: View) {
startActivity(Intent(this, MainActivity::class.java))
}
}
如果您对代码有任何问题,请随时问我。
英文:
I use MediaSession
to respond to headset media buttons, and want to stop the sound when activity is paused. I also want to make the headset media buttons not active when activity is paused.
From the android documentation, it said the setActive
method is use to "set if this session is currently active and ready to receive commands". But it not worked, I can still use head resume the music when activity is paused. Do I misunderstand the function of this method?
My code is as followed:
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class MainActivity : AppCompatActivity() {
private lateinit var mediaSession: MediaSession
private var mediaPlayer: MediaPlayer? = null
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mediaPlayer = MediaPlayer.create(this, R.raw.lapple)
mediaPlayer?.isLooping = true
mediaPlayer?.start()
// Create a MediaSessionCompat
mediaSession = MediaSession(this, "test_log").apply {
// Enable callbacks from MediaButtons and TransportControls
setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS or MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS)
// Do not let MediaButtons restart the player when the app is not visible
setMediaButtonReceiver(null)
// Set an initial PlaybackState with ACTION_PLAY, so media buttons can start the player
val stateBuilder = PlaybackState.Builder()
.setActions(PlaybackState.ACTION_PLAY or PlaybackState.ACTION_PAUSE or PlaybackState.ACTION_PLAY_PAUSE)
setPlaybackState(stateBuilder.build())
// MySessionCallback has methods that handle callbacks from a media controller
setCallback(object : MediaSession.Callback() {
override fun onPlay() {
Toast.makeText(
this@MainActivity,
"${this@MainActivity.hashCode()}: onPlay",
Toast.LENGTH_SHORT
).show()
mediaPlayer?.start()
}
override fun onPause() {
mediaPlayer?.pause()
Toast.makeText(
this@MainActivity,
"${this@MainActivity.hashCode()}: onPause",
Toast.LENGTH_SHORT
).show()
}
})
}
mediaSession.isActive = true
//mediaController = MediaController(this, mediaSession.sessionToken)
}
override fun onPause() {
super.onPause()
mediaSession.isActive = false
mediaPlayer?.pause()
}
override fun onResume() {
super.onResume()
mediaSession.isActive = true
mediaPlayer?.start()
}
override fun onDestroy() {
mediaPlayer?.release()
super.onDestroy()
}
fun newActivity(view: View) {
startActivity(Intent(this, MainActivity::class.java))
}
}
答案1
得分: 2
以下是翻译好的部分:
【文档】1中提到:
> 设置此会话是否当前处于活动状态并且准备好接收命令。如果设置为false,则可能无法发现会话的控制器。在会话开始接收媒体按钮事件或传输命令之前,必须将会话设置为活动状态。
文档没有提到您应该将其设置为false以停止接收命令。我猜想,如果控制器已经被发现,那么这个值就不再重要。
因此,根据这份文档,您应该使用release
或者setCallback(null)
。
英文:
The documentation says:
> Set if this session is currently active and ready to receive commands. If set to false your session's controller may not be discoverable. You must set the session to active before it can start receiving media button events or transport commands.
It does not say that you should set it to false to stop receiving commands. I guess if the controller is already discovered, the value doesn't matter anymore.
So instead you should use release
or setCallback(null)
according to this documentation.
答案2
得分: 1
以下是翻译好的部分:
<application>
<service
android:name=".service.MyService">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</service>
<!-- 这是多余的接收器,请不要这样做 ;-) -->
<receiver android:name="androidx.media.session.MediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
</application>
英文:
Just for the record: For me setCallback(null)
was not working, since I by mistake added two MEDIA_BUTTON.BroadcastReceiver
to Manifest.xml
. This somehow started the Service
in the background without attached Activity
<application>
<service
android:name=".service.MyService">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</service>
<!-- this was the stupid receiver. DO NOT DO IT ;-) -->
<receiver android:name="androidx.media.session.MediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
</application>
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论