Xamarin.Forms
DependencyServiceを使用したネイティブ機能へのアクセス
サーチ…
備考
インプリメンテーションが見つからないときにコードを中断しないようにするには、使用可能なインプリメンテーションがある場合はまずDependencyService
確認します。
null
でない場合、これを単純なチェックで行うことができnull
。
var speaker = DependencyService.Get<ITextToSpeech>();
if (speaker != null)
{
speaker.Speak("Ready for action!");
}
IDEがC#6をサポートしていて、NULL条件付き演算子を使用している場合:
var speaker = DependencyService.Get<ITextToSpeech>();
speaker?.Speak("Ready for action!");
これを行わず、実行時に実装が見つからない場合は、コードによって例外が生成されます。
テキスト読み上げの実装
プラットフォーム固有のコードを要求する機能の良い例は、テキスト読み上げ(tts)を実装する場合です。この例では、PCLライブラリの共有コードを使用していることを前提としています。
私たちのソリューションの概略図は、下の画像のようになります。
共有コードでは、 DependencyService
登録されているインタフェースを定義します。これが私たちが電話をする場所です。下にあるようなインターフェースを定義する。
public interface ITextToSpeech
{
void Speak (string text);
}
各プラットフォームで、このインタフェースの実装を作成する必要があります。 iOSの実装から始めましょう。
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);
}
}
上のコード例では、iOSに特定のコードがあることに気付きました。 AVSpeechSynthesizer
ようなタイプ。これらは共有コードでは機能しません。
この実装をXamarin DependencyService
登録するには、この属性を名前空間宣言の上に追加します。
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
これで共有コードでこのような呼び出しを行うと、アプリケーションを実行しているプラットフォームの適切な実装が行われます。
DependencyService.Get<ITextToSpeech>()
。これについては後で詳しく説明します。
Android実装
このコードのAndroidの実装は、下のようになります。
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
}
もう一度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
Windows Phoneの実装
最後に、Windows Phoneの場合、このコードを使用することができます。
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);
}
}
そしてもう一度それを登録することを忘れないでください。
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
共有コードでの実装
今はそれを動作させるためにすべての場所にあります!最後に、共有コードで、この関数をインターフェイスを使用して呼び出すことができます。実行時に、実行されている現在のプラットフォームに対応する実装が注入されます。
このコードでは、Xamarinフォームプロジェクトに含まれるページが表示されます。 DependencyService
を使用してSpeak()
メソッドを呼び出すボタンを作成します。
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;
}
結果は、アプリケーションが実行され、ボタンがクリックされると、提供されたテキストが話されることになります。
コンパイラのヒントなどのようなハードなことをする必要はありません。これで、プラットフォームに依存しないコードを使用して、プラットフォーム固有の機能にアクセスする統一された方法が実現しました。
アプリケーションとデバイスのOSバージョン番号の取得 - Android&iOS - PCL
以下の例では、Androidのバージョン名とiOSのバージョンに入力されたデバイスのOSバージョン番号とアプリケーションのバージョン(各プロジェクトのプロパティで定義されています)を収集します。
まず、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();
}
AndroidとiOSプロジェクトにインターフェイスを実装します。
アンドロイド:
[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; }
}
}
コードをメソッドで使用するようになりました。
public string GetOsAndAppVersion {
INativeHelper helper = DependencyService.Get<INativeHelper>();
if(helper != null) {
string osVersion = helper.GetOsVersion();
string appVersion = helper.GetBuildNumber()
}
}