【问题标题】:How to use an interface如何使用接口
【发布时间】:2019-05-07 01:04:39
【问题描述】:

我正在尝试构建我的第一个 xamarin 应用程序,我正在使用表单构建它。该应用程序的功能之一是向用户发送位置,即使应用程序在后台也必须这样做。所以我偶然发现了 James Montemagno 的 GeolocatorPlugin,它承诺可以做到这一点。

由于文档对如何在后台实现他的插件不是很清楚,我查看了项目关闭的问题并找到了一个人,他给出了一个使用插件和服务的简单案例的例子。 (https://github.com/jamesmontemagno/GeolocatorPlugin/issues/272)

我采用了代码并创建了服务。该服务正在使用一个接口来启动服务,现在我的问题是如何利用该接口来使服务运行。

在我的共享项目中,我放置了界面和视图模型,在 xamarin.android 项目中,我放置了服务。

接口 - IGeolocationBackgroundService:

public interface IGeolocationBackgroundService {
    void StartService();
    void StartTracking();
}

视图模型 - GeolocatorPageViewModel:

public class GeolocatorPageViewModel
{
    public Position _currentUserPosition { get; set; }
    public string CoordinatesString { get; set; }
    public List<string> userPositions { get; set; }

    public ICommand StartTrackingCommand => new Command(async () =>
    {
        if (CrossGeolocator.Current.IsListening)
        {
            await CrossGeolocator.Current.StopListeningAsync();
        }

        CrossGeolocator.Current.DesiredAccuracy = 25;
        CrossGeolocator.Current.PositionChanged += Geolocator_PositionChanged;

        await CrossGeolocator.Current.StartListeningAsync(
            TimeSpan.FromSeconds(3), 5);
    });

    private void Geolocator_PositionChanged(object sender, PositionEventArgs e)
    {
        var position = e.Position;
        _currentUserPosition = position;
        var positionString = $"Latitude: {position.Latitude}, Longitude: {position.Longitude}";
        CoordinatesString = positionString;
        Device.BeginInvokeOnMainThread(() => CoordinatesString = positionString);
        userPositions.Add(positionString);
        Debug.WriteLine($"Position changed event. User position: {CoordinatesString}");
    }
}

服务 - GeolocationService:

[assembly: Xamarin.Forms.Dependency(typeof(GeolocationService))]
namespace MyApp.Droid.Services
{
[Service]
public class GeolocationService : Service, IGeolocationBackgroundService
{
    Context context;

    private static readonly string CHANNEL_ID = "geolocationServiceChannel";
    public GeolocatorPageViewModel ViewModel { get; private set; }

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public GeolocationService(Context context)
    {
        this.context = context;
        CreateNotificationChannel();
    }

    private void CreateNotificationChannel()
    {
        NotificationChannel serviceChannel = new NotificationChannel(CHANNEL_ID,
            "GeolocationService", Android.App.NotificationImportance.Default);
        NotificationManager manager = context.GetSystemService(Context.NotificationService) as NotificationManager;

        manager.CreateNotificationChannel(serviceChannel);

    }

    //[return: GeneratedEnum]
    public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
    {
        var newIntent = new Intent(this, typeof(MainActivity));
        newIntent.AddFlags(ActivityFlags.ClearTop);
        newIntent.AddFlags(ActivityFlags.SingleTop);

        var pendingIntent = PendingIntent.GetActivity(this, 0, newIntent, 0);

        var builder = new Notification.Builder(this, CHANNEL_ID);
        var notification = builder.SetContentIntent(pendingIntent)
            .SetSmallIcon(Resource.Drawable.ic_media_play_light)
            .SetAutoCancel(false)
            .SetTicker("Locator is recording")
            .SetContentTitle("GeolocationService")
            .SetContentText("Geolocator is recording for position changes.")
            .Build();

        StartForeground(112, notification);
        //ViewModel = new GeolocatorPageViewModel();
        return StartCommandResult.Sticky;
    }


    public void StartService()
        => context.StartService(new Intent(context, typeof(GeolocationService)));


    public void StartTracking()
    {
        ViewModel = new GeolocatorPageViewModel();
        ViewModel.StartTrackingCommand.Execute(null);
    }
}
}

所以说清楚了,我需要启动服务,而且我不习惯接口,那么如何调用接口呢?

【问题讨论】:

  • 我不清楚您的实际问题是什么?
  • 我刚刚把我的问题加粗了:)

标签: xamarin interface


【解决方案1】:

使用 DependencyService 获取对您的服务的引用,然后启动它

var svc = DependencyService.Get<IGeolocationBackgroundService>();
svc.StartService();
svc.StartTracking();

【讨论】:

  • 好的,它可以调用该服务,但是当它调用该服务时,我会得到: 'MyApp.Droid.Services.GeolocationService' 类型必须提供一个公共默认构造函数 - 如果我创建一个空构造函数,上下文一片空白。这是一个新问题,还是我必须换一种说法?
  • 不确定这是否适用于 bg 服务,但github.com/jamesmontemagno/CurrentActivityPlugin
猜你喜欢
  • 2012-06-25
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多