Où écouter l'action diffusée avec MVVMCross
-
12-12-2019 - |
Question
Pour créer mon application Bluetooth, j'ai besoin d'accéder à certaines actions de diffusion du côté Android de mon code.
Tout cela est exécuté dans mon Core, j'ai donc un ViewModel qui appellera via mon interface
public interface IConnectionService
{
//Properties
string IntentName { get; }
//Events
event EventHandler<SearchConnectionItemEventArgs> SearchItemFoundEvent;
//Methods
void RunIntent();
void SearchConnection();
void Connect(string macAddress);
}
RunIntent invite l'utilisateur à activer Bluetooth (cela pourrait être une autre technologie) et j'aimerais alors avoir un déclencheur d'événement lorsque l'état Bluetooth est modifié
Android.Bluetooth.BluetoothAdapter.ActionStateChanged
Et aussi lorsque je recherche de nouveaux appareils dont j'ai besoin
Android.Bluetooth.BluetoothDevice.ActionFound
Mais je ne peux pas mettre les [Android.Runtime.Register("ACTION_FOUND")] et [Android.Runtime.Register("ACTION_STATE_CHANGED")] sur ma classe, cela ne fonctionne que si j'essaie de le mettre sur ma vue, mais si je est-ce que j'ai besoin de logique à mon avis ?
Est-il possible de le mettre dans le noyau d'une manière ou d'une autre ?
Ma classe implémentant mon interface
using System;
using Android.Bluetooth;
using Android.Content;
using Cirrious.MvvmCross.Android.Platform.Tasks;
using Test.Core.Interfaces;
using Test.Core.Models;
namespace Test.Core.Android
{
public class AndroidBluetooth : MvxAndroidTask, IConnectionService
{
#region Private Fields
private readonly BluetoothAdapter _bluetoothAdapter;
#endregion
#region Public Fields
#endregion
#region Properties
public string IntentName { get { return "Turn on Bluetooth"; }}
#endregion
#region Constructor
public AndroidBluetooth()
{
_bluetoothAdapter = BluetoothAdapter.DefaultAdapter;
}
#endregion
#region Events
public event EventHandler<SearchConnectionItemEventArgs> SearchItemFoundEvent;
private void ItemFound(SearchConnectionItemEventArgs e)
{
if(SearchItemFoundEvent != null)
{
SearchItemFoundEvent(this, e);
}
}
#endregion
#region Methods
public void RunIntent()
{
if (_bluetoothAdapter == null)
{
//No bluetooth support on phone
}
else if(!_bluetoothAdapter.IsEnabled)
{
var intent = new Intent(BluetoothAdapter.ActionRequestEnable);
StartActivity(intent);
}
}
public void SearchConnection()
{
if (_bluetoothAdapter == null)
{
//No bluetooth support on phone
}
else if (!_bluetoothAdapter.IsEnabled)
{
//Bluetooth not turned on
RunIntent();
}
else
{
FindBondedDevices();
}
}
private void FindBondedDevices()
{
var pairedDevices = _bluetoothAdapter.BondedDevices;
if (pairedDevices.Count <= 0) return;
foreach (var item in pairedDevices)
{
ItemFound(new SearchConnectionItemEventArgs {Name = item.Name, MacAddress = item.Address});
}
}
private void FindNewDevices()
{
if (_bluetoothAdapter == null)
{
}
else if (!_bluetoothAdapter.IsEnabled)
{
}
else
{
_bluetoothAdapter.StartDiscovery();
//Bind event for new devices
}
}
public void Connect(string macAddress)
{
}
#endregion
}
}
La solution
Clause de non-responsabilité:Je ne connais pas cette partie d'Android – je n'ai jamais utilisé la pile Bluetooth.
D'après votre description, il semble que vous connaissiez déjà la réponse - ces attributs doivent être placés dans des méthodes au sein de l'activité/vue.
Bien sûr, une fois qu'ils ont été ajoutés à Activity/View, il est facile d'acheminer ces appels de méthode vers ViewModel - utilisez simplement le ViewModel
propriété dans la vue.
Il est probablement plus facile d'essayer d'abord de faire fonctionner cette partie de votre travail en tant qu'échantillon autonome - puis de trouver comment la rendre multiplateforme et/ou mvvm.