【问题标题】:Is it possible to develop a CarPlay app using Xamarin tools是否可以使用 Xamarin 工具开发 CarPlay 应用程序
【发布时间】:2019-05-11 19:33:01
【问题描述】:

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

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

附:我做了更多的研究,虽然你可以为 CarPlay 开发应用程序,但 Apple 在撰写本文时只允许导航和流媒体应用程序。因此,对于我想做的事情来说,这完全不是初学者。

【问题讨论】:

    标签: c# visual-studio xamarin


    【解决方案1】:

    是的,这是可能的。 我做了一个blog post 和一个GitHub 的例子。


    简而言之,答案如下:

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

    代表注册如下:

    public class CarIntegrationBridge : ICarIntegrationBridge
    {
      public static void Init()
      {
        PlayableContentDelegate playableContentDelegate = new PlayableContentDelegate();
        MPPlayableContentManager.Shared.Delegate = playableContentDelegate;
        PlayableContentDataSource playableContentDataSource = new PlayableContentDataSource();
        MPPlayableContentManager.Shared.DataSource = playableContentDataSource;
      }
    }
    

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

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

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

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

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

    public void ReloadStations()
    {
      MPPlayableContentManager.Shared?.ReloadData();
    }
    

    【讨论】:

      【解决方案2】:

      也许这个https://forums.xamarin.com/discussion/144790/android-auto-ios-car-play 回答了这个问题?

      Car Play 似乎是 Apple 方面的一个私有框架。 XCode 没有相关文档。

      对于 Android Auto,去 github,搜索项目 Xamarin_Android_Auto_Test

      【讨论】:

      • 这是一个旧答案,该框架现在是开放的,但仅对流媒体和导航应用程序开放,所以它不是我想要的。
      猜你喜欢
      • 1970-01-01
      • 2016-07-29
      • 2016-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      相关资源
      最近更新 更多