我正在开发音乐播放器应用。现在,当我上车时,我的汽车通过蓝牙自动连接到手机,并始终发出“媒体播放”意图。因此,现在无论使用什么应用程序监听意图,都应该为我“播放”它存储的所有媒体。 但我一直希望“那个应用”成为我的音乐播放器。
所以,这就是我所做的。
我设置了一个粘性服务,用于注册媒体按钮接收器。 现在,即使该应用程序较早被销毁,该接收器也应能够捕获所有传入的意图并播放歌曲。
尽管收款机运行正常,但一旦关闭应用程序,它将不再收到任何内容。我测试过,当耳机单击播放按钮时,该应用程序应该发出一条吐司消息,说“ 0”。但是,只有当我的应用明显处于后台或后台时,才会显示“ 0”。
如果该应用程序被杀死并且我按下了耳机挂钩(或连接了我的汽车),则标准媒体播放器始终会干扰那里的任何播放歌曲。但这正是我要避免的事情。
如何使我的广播接收器领先于其他接收器?这就是我所做的:
服务类(粘性,并注册接收者)
[Service]
public class ServiceClass : Service
{
private int _countDownFirstRound;
private Notification.Builder notificationBuilder;
private Handler handler;
private Action runnable;
MediaSession mMediaSession;
AudioManager mAudioManager;
RemoteControlClient mRemoteControlClient;
private IntentReceiver intentReceiver;
private IntentFilter intentFilter = new IntentFilter(Intent.ActionMediaButton);
public override void OnCreate()
{
base.OnCreate();
_countDownFirstRound = 0;
handler = new Handler();
runnable = new Action(() => { });
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
SetOreoNotification();
}
else
{
DispatchNotificationThatServiceIsRunning();
}
InitBluetoohSending();
return StartCommandResult.Sticky;
}
public override IBinder OnBind(Intent intent)
{
return null;
}
public override void OnDestroy()
{
base.OnDestroy();
handler.RemoveCallbacks(runnable);
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Cancel(50);
notificationManager.Dispose();
}
private void InitBluetoohSending()
{
mAudioManager = (AudioManager)GetSystemService(AudioService);
if (mAudioManager == null)
{
mAudioManager = (AudioManager)GetSystemService(AudioService);
}
if (Build.VERSION.SdkInt < Build.VERSION_CODES.Lollipop)
{
if (mRemoteControlClient == null)
{
mRemoteControlClient = new RemoteControlClient(PendingIntent.GetBroadcast(this, 0, new Intent(Intent.ActionMediaButton), 0));
mAudioManager.RegisterRemoteControlClient(mRemoteControlClient);
}
}
else
{
if (mMediaSession == null)
{
mMediaSession = new MediaSession(this, "PlayerServiceMediaSession");
mMediaSession.SetFlags(MediaSession.FlagHandlesTransportControls);
mMediaSession.SetFlags(MediaSession.FlagHandlesMediaButtons);
mMediaSession.Active = true;
mMediaSession.SetCallback(new MediaButtonReceiver(this, null));
}
}
}
}
还有MediaButtonrecevier,它在应用被杀死时不会响应:
public class MediaButtonReceiver : MediaSession.Callback
{
static long lastClick = 0;
Context ctx;
Activity_Player act;
public MediaButtonReceiver(Context ctx, Activity_Player act)
{
this.ctx = ctx;
this.act = act;
}
public override bool OnMediaButtonEvent(Intent mediaButtonIntent)
{
if (mediaButtonIntent.Action != Intent.ActionMediaButton)
return false;
var keyEvent = (KeyEvent)mediaButtonIntent.GetParcelableExtra(Intent.ExtraKeyEvent);
switch (keyEvent.KeyCode)
{
case Keycode.Headsethook:
if (canClick())
Toast.MakeText(ctx, "0", ToastLength.Short).Show();
//act.PlayOrPauseLogic(true);
break;
}
return base.OnMediaButtonEvent(mediaButtonIntent);
}
private bool canClick()
{
if (lastClick < Java.Lang.JavaSystem.CurrentTimeMillis() - 700) // needs to be atleast one second bigger
{
lastClick = Java.Lang.JavaSystem.CurrentTimeMillis();
return true;
}
else
return false;
}
}