是否可以使用 Xamarin 工具开发 CarPlay 应用程序

Ang*_*ker 3 c# visual-studio xamarin

正如标题所述,我正在尝试为我的汽车构建一个应用程序。我只在 Xamarin 文档中看到对 CarPlay 的简短提及。

那么是否可以使用 Xamarin 和 Visual Studio 工具开发 CarPlay 应用程序?

PS:我做了一些更多的研究,虽然你可以为 CarPlay 开发应用程序,但截至撰写本文时,Apple 只允许导航和流媒体应用程序。所以这对于我想做的事情来说完全是不可能的。

Sup*_*nus 5

是的,这是可能的。\n我在GitHub上发表了一篇博文和一个示例。

\n
\n

简而言之,答案如下:

\n

在我们的 iOS 项目中,我们使用 来初始化 AppDelegate.cs 中的委托 CarIntegrationBridge.Init();

\n

代表登记如下:

\n
public class CarIntegrationBridge : ICarIntegrationBridge\n{\n  public static void Init()\n  {\n    PlayableContentDelegate playableContentDelegate = new PlayableContentDelegate();\n    MPPlayableContentManager.Shared.Delegate = playableContentDelegate;\n    PlayableContentDataSource playableContentDataSource = new PlayableContentDataSource();\n    MPPlayableContentManager.Shared.DataSource = playableContentDataSource;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在我们定义我们的数据源。在我的示例中,我添加了带有名称和网址的广播电台。我们必须定义菜单项的数量以及菜单项的显示方式(名称、图标、\xe2\x80\xa6):

\n
internal class PlayableContentDataSource : MPPlayableContentDataSource\n{\n  public static List<Station> Stations = new List<Station>\n  {\n    new Station{Name = "Rainbow radio", Url = "https://stream.rockantenne.de/rockantenne/stream/mp3"},\n    new Station{Name = "Unicorn radio", Url = "http://play.rockantenne.de/heavy-metal.m3u"}\n  };\n  \n  public override MPContentItem ContentItem(NSIndexPath indexPath)\n  {\n    var station = Stations[indexPath.Section];\n    var item = new MPContentItem(station.Url);\n    item.Title = station.Name;\n    item.Playable = true;\n    item.StreamingContent = true;\n    var artWork = GetImageFromUrl("station.png");\n    if (artWork != null)\n    {\n      item.Artwork = artWork;\n    }\n    return item;\n  }\n  public override nint NumberOfChildItems(NSIndexPath indexPath)\n  {\n    if (indexPath.GetIndexes().Length == 0)\n    {\n      return Stations.Count;\n    }\n    throw new NotImplementedException();\n  }\n  private MPMediaItemArtwork GetImageFromUrl(string imagePath)\n  {\n    MPMediaItemArtwork result = null;\n    try\n    {\n      using (var nsUrl = new NSUrl(imagePath))\n      {\n        using (var data = NSData.FromUrl(nsUrl))\n        {\n          var image = UIImage.LoadFromData(data);\n          result = new MPMediaItemArtwork(image);\n        }\n      }\n    }\n    catch\n    {\n      UIImage image = UIImage.FromBundle(imagePath);\n      if (image != null)\n      {\n        result = new MPMediaItemArtwork(image);\n      }\n    }\n    return result;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在,如果某个项目被录制,我们必须决定要做什么。\n模拟器具有与真实设备不同的行为。所以我编写了一个调用 NowPlayingScene 的解决方案。

\n
internal class PlayableContentDelegate : MPPlayableContentDelegate\n{\n  public override void InitiatePlaybackOfContentItem(\n    MPPlayableContentManager contentManager, NSIndexPath indexPath, Action<NSError> completionHandler)\n  {\n    Execute(contentManager, indexPath);\n    completionHandler?.Invoke(null);\n  }\n  private void Execute(MPPlayableContentManager contentManager, NSIndexPath indexPath)\n  {\n    DispatchQueue.MainQueue.DispatchAsync(async () => await ItemSelectedAsync(contentManager, indexPath));\n  }\n  private async Task ItemSelectedAsync(MPPlayableContentManager contentManager, NSIndexPath indexPath)\n  {\n    // Play\n    var station = PlayableContentDataSource.Stations[indexPath.Section];\n    await CrossMediaManager.Current.Play(station.Url);\n    // Set playing identifier\n    MPContentItem item = contentManager.DataSource.ContentItem(indexPath);\n    contentManager.NowPlayingIdentifiers = new[] { item.Identifier };\n    // Update on simulator\n    if (DeviceInfo.DeviceType == DeviceType.Virtual)\n    {\n      InvokeOnMainThread(() =>\n      {\n        UIApplication.SharedApplication.EndReceivingRemoteControlEvents();\n        UIApplication.SharedApplication.BeginReceivingRemoteControlEvents();\n      });\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

要重新加载数据(例如,如果您更改电台),您必须调用以下命令:

\n
public void ReloadStations()\n{\n  MPPlayableContentManager.Shared?.ReloadData();\n}\n
Run Code Online (Sandbox Code Playgroud)\n