如何解决Xamarin 在依赖注入中覆盖 RemoteControlReceived
我试图覆盖 UIApplication 的 RemoteControlRecieved 方法并收到以下错误:
NSInternalInconsistencyException 原因:只能有一个 UIApplication 实例。
我明白这个问题,但不知道如何解决它。我有一个 StreamingService 类,它实现了 UIApplication 和 IStreaming 接口。我所有的 AVPlayer 功能都在这个类中。 Streamingviewmodel 类调用
DependencyService.Get<IStreaming>().Play().
调用此行时,出现上述错误。我不确定如何从 StreamingService 或 Streamingviewmodel 类覆盖 RemoteControlRecieved。
非常感谢您对代码示例的任何帮助。
以下课程
public class Streamingviewmodel : INotifyPropertyChanged
{
public bool displayPlay { get => !isPlaying; }
public bool displayPauseStop { get => isPlaying; }
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
}
bool isPlaying;
bool IsPlaying
{
get => isPlaying;
set
{
isPlaying = value;
// Notify the property has changed
OnPropertyChanged("displayPlay");
OnPropertyChanged("displayPauseStop");
}
}
public void Play()
{
DependencyService.Get<IStreaming>().Play();
IsPlaying = true;
}
public void Pause()
{
DependencyService.Get<IStreaming>().Pause();
IsPlaying = false;
}
public void Stop()
{
DependencyService.Get<IStreaming>().Stop();
IsPlaying = false;
}
}
流媒体服务类
[assembly: Xamarin.Forms.ExportRenderer(typeof(MainPage),typeof(StreamingService))]
[assembly: Dependency(typeof(StreamingService))]
namespace test.iOS
{
public class StreamingService : PageRenderer,IStreaming
{
AVPlayer player;
bool isPrepared;
string dataSource = "https://stream.voxx.pro/radio/8260/radio.mp3";
public override void ViewDidLoad()
{
Console.WriteLine("StreamService ViewDidLoad");
base.ViewDidLoad();
}
public StreamingService()
{
Console.WriteLine("StreamService Default Constructor");
}
public void Play()
{
Console.WriteLine("Play");
if (!isPrepared || player == null)
player = AVPlayer.FromUrl(NSUrl.FromString(dataSource));
//Audio player Notification in lock screen
MPNowPlayingInfo NowPlayingInfo;
NowPlayingInfo = new MPNowPlayingInfo();
NowPlayingInfo.Artist = "Radio Caravan";
NowPlayingInfo.Title = "Join The Caravan";
// Register for receiving controls from lock screen and controlscreen
MPNowPlayingInfoCenter.DefaultCenter.NowPlaying = NowPlayingInfo;
//var command = MPRemoteCommandCenter.Shared;
//command.PlayCommand.Enabled = true;
//command.PauseCommand.Enabled = true;
//command.NextTrackCommand.Enabled = false;
//command.PrevIoUsTrackCommand.Enabled = false;
isPrepared = true;
player.Play();
base.BecomeFirstResponder();
//To listen changes in lock screen
UIApplication.SharedApplication.BeginReceivingRemoteControlEvents();
}
public void Pause()
{
player.Pause();
}
public void Stop()
{
player.dispose();
isPrepared = false;
}
public override void RemoteControlReceived(UIEvent theEvent)
{
Console.WriteLine("Remote Control Received");
base.RemoteControlReceived(theEvent);
if (theEvent.Subtype == UIEventSubtype.RemoteControlPause)
{
Console.WriteLine("Remote Pause");
player.Pause();
}
else if (theEvent.Subtype == UIEventSubtype.RemoteControlPlay)
{
Console.WriteLine("Remote Play");
player.Play();
}
}
}
}
MainPage.cs
namespace test
{
public partial class MainPage : ContentPage
{
private Streamingviewmodel viewmodel { get { return (Streamingviewmodel)this.BindingContext; } }
public MainPage()
{
InitializeComponent();
On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(true);
BindingContext = new Streamingviewmodel();
}
// Callbacks to images tapped
private void Play_tapped(object sender,EventArgs e)
{
viewmodel.Play();
}
private void Pause_tapped(object sender,EventArgs e)
{
viewmodel.Pause();
}
private void Stop_tapped(object sender,EventArgs e)
{
viewmodel.Stop();
}
}
}
接口:IStreaming
public interface IStreaming
{
void Play();
void Pause();
void Stop();
}
解决方法
NSInternalInconsistencyException 原因:只能有一个 UIApplication 实例。
您可以自定义 PageRenderer 来覆盖 RemoteControlReceived 方法以检查它是否有效。因为这将使用现有的 UIApplication
。
关于 isPlaying
属性,您可以使用 Bindable Properties 在 CustomPage 中定义。
关于 Play/Pause/Stop
方法,您可以使用 MessagingCenter 将消息从表单发送到 CustomPageRenderer。
例如CustomPage的部分代码如下:
public partial class CustomPage: ContentPage
{
public CustomPage()
{
InitializeComponent();
}
public static readonly BindableProperty IsPlayingProperty = BindableProperty.Create("IsPlaying",typeof(bool),typeof(CustomPage),null);
public bool IsPlaying
{
get { return (bool)GetValue(IsPlayingProperty); }
set { SetValue(IsPlayingProperty,value); }
}
public void Play()
{
MessagingCenter.Send<object,string>(this,"PlayControl","Play");
IsPlaying = true;
}
public void Pause()
{
MessagingCenter.Send<object,"Pause");
IsPlaying = false;
}
public void Stop()
{
MessagingCenter.Send<object,"Stop");
IsPlaying = false;
}
}
CustomPageRenderer的部分代码如下:
[assembly: Xamarin.Forms.ExportRenderer(typeof(CustomPage),typeof(CustomPageRenderer))]
namespace XamarinForms20.iOS
{
public class CustomPageRenderer : PageRenderer
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
//...
MessagingCenter.Subscribe<object,(sender,arg) =>
{
if(arg == "Play")
{
//...
}else if (arg == "Pause")
{
//...
}else if (arg == "Stop")
{
//...
}
});
}
public override void RemoteControlReceived(UIEvent theEvent)
{
base.RemoteControlReceived(theEvent);
if (theEvent.Subtype == UIEventSubtype.RemoteControlPlay)
player.Play();
else if (theEvent.Subtype == UIEventSubtype.RemoteControlPause)
player.Pause();
}
}
}
====================================更新========== ======================
您可以尝试在 AVAudioSession.InterruptionNotification 的 NSNotificationCenter
方法中添加 ViewDidload
。
public override void ViewDidLoad()
...
NSObject _notificationHandle = NSNotificationCenter.DefaultCenter.AddObserver(AVAudioSession.InterruptionNotification,HandleNotification);
...
private void HandleNotification(NSNotification notification)
{
// Do something
NSDictionary userinfo = notification.UserInfo;
NSNumber number = (NSNumber)userinfo.ValueForKey(new NSString("AVAudioSessionInterruptionTypeKey"));
int value = (int)number.NIntValue;
if(value == 1)
{
// pause
}else if(value == 0)
{
// countinue to play
AVAudioSession.SharedInstance().SetActive(true);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。