Я работаю над приложением музыкального проигрывателя. Теперь, когда я захожу в свою машину, моя машина автоматически подключается к телефону через Bluetooth и всегда отправляет сигнал «воспроизведения мультимедиа». Так что, какое бы приложение ни слушало намерения, теперь оно должно «воспроизводить» любые медиа, которые оно хранит для меня.
Но я всегда хочу, чтобы «это приложение» было моим музыкальным проигрывателем.
Итак, вот что я сделал.
Я установил липкий сервис, который регистрировал бы приемник медиа кнопки.
Предполагается, что теперь этот получатель будет перехватывать все входящие намерения и проигрывать песню, даже если приложение было ранее уничтожено.
Хотя получатель работает просто отлично, как только приложение закрывается, оно больше ничего не получает. Я проверил это, когда, когда гарнитура нажимает кнопку воспроизведения, приложение должно выдавать всплывающее сообщение «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;
}
}