В Xamarin iOS, вам нужно настроить его в Capabilities проекта, чтобы сначала включить фоновый режим в info.plist
.
Затем вам нужно добавить следующий код в AppDelegate.cs
:
public bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
// Override point for customization after application launch.
// If not required for your application you can safely delete this method
AVAudioSession session = AVAudioSession.SharedInstance();
session.SetCategory(AVAudioSessionCategory.Playback);
session.SetActive(true);
return true;
}
Затем вы можете создать образец аудиоплеера с помощью AVPlayer :
public partial class ViewController : UIViewController
{
public AVAudioPlayer player;
public float MusicVolume
{
get;
set;
} = 0.5f;
public bool MusicOn
{
get;
set;
} = true;
public ViewController (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
}
public override void DidReceiveMemoryWarning ()
{
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
partial void UIButtonPlay_TouchUpInside(UIButton sender)
{
//throw new NotImplementedException();
Console.WriteLine("play");
PlayMusic();
}
public void PlayMusic()
{
NSUrl songURL;
if (!MusicOn) return;
//Song url from your local Resource
songURL = new NSUrl("Sounds/Alan_Walker.mp3");
NSError err;
player = new AVAudioPlayer(songURL, "Song", out err);
player.Volume = MusicVolume;
player.FinishedPlaying += delegate {
// backgroundMusic.Dispose();
player = null;
};
//Background Music play
player.Play();
}
partial void UIButtonStop_TouchUpInside(UIButton sender)
{
//throw new NotImplementedException();
Console.WriteLine("stop");
player.Stop();
}
public override void RemoteControlReceived(UIEvent theEvent)
{
base.RemoteControlReceived(theEvent);
Console.WriteLine("RemoteControlReceived");
switch (theEvent.Subtype)
{
case UIEventSubtype.RemoteControlPlay:
//play the music
Console.WriteLine("Remote Play"); player.Play();
break;
case UIEventSubtype.RemoteControlPause:
//pause the music
Console.WriteLine("Remote Stop"); player.Stop();
break;
case UIEventSubtype.RemoteControlNextTrack:
//play next one
break;
case UIEventSubtype.RemoteControlPreviousTrack:
//play last one
break;
dafault:
break;
}
}
}
Наконец, вы можете добавить фоновый контроль при DidEnterBackground
и DidBecomeActive
. С iOS 13 метонд жизненного цикла был перемещен с AppDelegate
на SceneDelegate
.
public class SceneDelegate : UIResponder, IUIWindowSceneDelegate
{
[Export("window")]
public UIWindow Window { get; set; }
[Export("scene:willConnectToSession:options:")]
public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions)
{
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead).
}
[Export("sceneDidDisconnect:")]
public void DidDisconnect(UIScene scene)
{
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead).
}
[Export("sceneDidBecomeActive:")]
public void DidBecomeActive(UIScene scene)
{
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
UIApplication.SharedApplication.EndReceivingRemoteControlEvents();
}
[Export("sceneWillResignActive:")]
public void WillResignActive(UIScene scene)
{
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
[Export("sceneWillEnterForeground:")]
public void WillEnterForeground(UIScene scene)
{
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
[Export("sceneDidEnterBackground:")]
public void DidEnterBackground(UIScene scene)
{
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
UIApplication.SharedApplication.BeginReceivingRemoteControlEvents();
SetLockInfo();
}
public void SetLockInfo()
{
//NSMutableDictionary songInfo = new NSMutableDictionary();
MPNowPlayingInfo playInfo = new MPNowPlayingInfo();
//image
MPMediaItemArtwork albumArt = new MPMediaItemArtwork(new UIImage());
playInfo.Artwork = albumArt;
//title
playInfo.Title = "your song name";
//singer
playInfo.Artist = "singer name";
//rate
playInfo.PlaybackRate = 1.0;
//current time
playInfo.ElapsedPlaybackTime = 0;
//durtaion
playInfo.PlaybackDuration = 2.35; // the durtaion of the song
MPNowPlayingInfoCenter.DefaultCenter.NowPlaying = playInfo;
}
}
При входе в фоновый режим необходимо передавать текущую аудиоинформацию в MPNowPlayingInfoCenter .