Xamarin.Forms
Accès aux fonctionnalités natives avec DependencyService
Recherche…
Remarques
Si vous ne voulez pas que votre code se brise lorsqu'aucune implémentation n'est trouvée, vérifiez d'abord le DependencyService
s'il dispose d'une implémentation disponible.
Vous pouvez le faire par une simple vérification si elle n'est pas null
.
var speaker = DependencyService.Get<ITextToSpeech>();
if (speaker != null)
{
speaker.Speak("Ready for action!");
}
ou, si votre IDE prend en charge C # 6, avec un opérateur conditionnel nul:
var speaker = DependencyService.Get<ITextToSpeech>();
speaker?.Speak("Ready for action!");
Si vous ne le faites pas et qu'aucune implémentation n'est trouvée à l'exécution, votre code générera une exception.
Mise en œuvre de la synthèse vocale
Un bon exemple de fonctionnalité qui demande un code spécifique à la plate-forme consiste à implémenter le text-to-speech (tts). Cet exemple suppose que vous travaillez avec du code partagé dans une bibliothèque PCL.
Un aperçu schématique de notre solution ressemblerait à l'image ci-dessous.
Dans notre code partagé, nous définissons une interface qui est enregistrée avec DependencyService
. C'est là que nous ferons appel à nous. Définir une interface comme ci-dessous.
public interface ITextToSpeech
{
void Speak (string text);
}
Maintenant, dans chaque plate-forme spécifique, nous devons créer une implémentation de cette interface. Commençons par l'implémentation iOS.
Mise en œuvre iOS
using AVFoundation;
public class TextToSpeechImplementation : ITextToSpeech
{
public TextToSpeechImplementation () {}
public void Speak (string text)
{
var speechSynthesizer = new AVSpeechSynthesizer ();
var speechUtterance = new AVSpeechUtterance (text) {
Rate = AVSpeechUtterance.MaximumSpeechRate/4,
Voice = AVSpeechSynthesisVoice.FromLanguage ("en-US"),
Volume = 0.5f,
PitchMultiplier = 1.0f
};
speechSynthesizer.SpeakUtterance (speechUtterance);
}
}
Dans l'exemple de code ci-dessus, vous remarquez qu'il existe un code spécifique à iOS. Comme les types tels que AVSpeechSynthesizer
. Celles-ci ne fonctionneraient pas dans le code partagé.
Pour enregistrer cette implémentation avec Xamarin DependencyService
ajoutez cet attribut au-dessus de la déclaration d'espace de noms.
using AVFoundation;
using DependencyServiceSample.iOS;//enables registration outside of namespace
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.iOS {
public class TextToSpeechImplementation : ITextToSpeech
//... Rest of code
Maintenant, lorsque vous faites un appel comme celui-ci dans votre code partagé, la bonne implémentation de la plate-forme sur laquelle vous exécutez votre application est injectée.
DependencyService.Get<ITextToSpeech>()
. Plus à ce sujet plus tard.
Implémentation Android
L'implémentation Android de ce code ressemblerait à celle ci-dessous.
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
public class TextToSpeechImplementation : Java.Lang.Object, ITextToSpeech, TextToSpeech.IOnInitListener
{
TextToSpeech speaker;
string toSpeak;
public TextToSpeechImplementation () {}
public void Speak (string text)
{
var ctx = Forms.Context; // useful for many Android SDK features
toSpeak = text;
if (speaker == null) {
speaker = new TextToSpeech (ctx, this);
} else {
var p = new Dictionary<string,string> ();
speaker.Speak (toSpeak, QueueMode.Flush, p);
}
}
#region IOnInitListener implementation
public void OnInit (OperationResult status)
{
if (status.Equals (OperationResult.Success)) {
var p = new Dictionary<string,string> ();
speaker.Speak (toSpeak, QueueMode.Flush, p);
}
}
#endregion
}
Encore une fois, n'oubliez pas de l'enregistrer avec le DependencyService
.
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.Droid{
//... Rest of code
Implémentation Windows Phone
Enfin, pour Windows Phone, ce code peut être utilisé.
public class TextToSpeechImplementation : ITextToSpeech
{
public TextToSpeechImplementation() {}
public async void Speak(string text)
{
MediaElement mediaElement = new MediaElement();
var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello World");
mediaElement.SetSource(stream, stream.ContentType);
mediaElement.Play();
await synth.SynthesizeTextToStreamAsync(text);
}
}
Et une fois de plus, n'oubliez pas de l'enregistrer.
using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Controls;
using DependencyServiceSample.WinPhone;//enables registration outside of namespace
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.WinPhone{
//... Rest of code
Implémentation en code partagé
Maintenant, tout est en place pour que ça marche! Enfin, dans votre code partagé, vous pouvez maintenant appeler cette fonction en utilisant l'interface. Lors de l'exécution, l'implémentation sera injectée, ce qui correspond à la plate-forme actuelle sur laquelle elle s'exécute.
Dans ce code, vous verrez une page qui pourrait être dans un projet Xamarin Forms. Il crée un bouton qui appelle la méthode Speak()
à l'aide de DependencyService
.
public MainPage ()
{
var speak = new Button {
Text = "Hello, Forms !",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
};
speak.Clicked += (sender, e) => {
DependencyService.Get<ITextToSpeech>().Speak("Hello from Xamarin Forms");
};
Content = speak;
}
Le résultat sera que lorsque l'application est exécutée et que le bouton est cliqué, le texte fourni sera prononcé.
Tout cela sans avoir à faire des choses difficiles comme des conseils de compilation et autres. Vous disposez désormais d'un moyen unique d'accéder aux fonctionnalités spécifiques à la plateforme via un code indépendant de la plate-forme.
Obtenir les numéros de version du système d’exploitation et d’appareils - Android & iOS - PCL
L'exemple ci-dessous collectera le numéro de version du système d'exploitation de l'appareil et la version de l'application (définie dans les propriétés de chaque projet) entrée dans Nom de la version sur Android et Version sur iOS.
Faites d'abord une interface dans votre projet PCL:
public interface INativeHelper {
/// <summary>
/// On iOS, gets the <c>CFBundleVersion</c> number and on Android, gets the <c>PackageInfo</c>'s <c>VersionName</c>, both of which are specified in their respective project properties.
/// </summary>
/// <returns><c>string</c>, containing the build number.</returns>
string GetAppVersion();
/// <summary>
/// On iOS, gets the <c>UIDevice.CurrentDevice.SystemVersion</c> number and on Android, gets the <c>Build.VERSION.Release</c>.
/// </summary>
/// <returns><c>string</c>, containing the OS version number.</returns>
string GetOsVersion();
}
Maintenant, nous implémentons l'interface dans les projets Android et iOS.
Android:
[assembly: Dependency(typeof(NativeHelper_Android))]
namespace YourNamespace.Droid{
public class NativeHelper_Android : INativeHelper {
/// <summary>
/// See interface summary.
/// </summary>
public string GetAppVersion() {
Context context = Forms.Context;
return context.PackageManager.GetPackageInfo(context.PackageName, 0).VersionName;
}
/// <summary>
/// See interface summary.
/// </summary>
public string GetOsVersion() { return Build.VERSION.Release; }
}
}
iOS:
[assembly: Dependency(typeof(NativeHelper_iOS))]
namespace YourNamespace.iOS {
public class NativeHelper_iOS : INativeHelper {
/// <summary>
/// See interface summary.
/// </summary>
public string GetAppVersion() { return Foundation.NSBundle.MainBundle.InfoDictionary[new Foundation.NSString("CFBundleVersion")].ToString(); }
/// <summary>
/// See interface summary.
/// </summary>
public string GetOsVersion() { return UIDevice.CurrentDevice.SystemVersion; }
}
}
Maintenant, utilisez le code dans une méthode:
public string GetOsAndAppVersion {
INativeHelper helper = DependencyService.Get<INativeHelper>();
if(helper != null) {
string osVersion = helper.GetOsVersion();
string appVersion = helper.GetBuildNumber()
}
}