演習: 電話番号変換アプリの作成
この演習では、ダイヤラー アプリの UI を構築し、この UI の背後のロジックを実装します。
.NET MAUI (Multi-platform Application User Interface) と .NET MAUI Essentials パッケージの UI 機能を利用して電話をかける UI を構築します。
ユーザーはこのアプリを使用して入力フィールドにテキストを入力し、そのテキストを数値に変換できます。 変換のベースとして電話キーパッドに表示される文字が使用されます。 たとえば、文字 cab は 222 に変換されます。これは、数字 2 に a、b、c の 3 つの文字がすべて含まれているためです。
前の演習で作成した Phoneword ソリューションを続行します。
新しい C# ソース ファイルをアプリに追加する
Phoneword ソリューションをまだ開いていない場合は、Visual Studio で開きます。
ソリューション エクスプローラー ウィンドウで、Phoneword プロジェクトを右クリックし、[追加]、[クラス] の順に選択します。
[新しい項目の追加] ダイアログ ボックスで、クラス ファイルに PhonewordTranslator.cs という名前を付けて、[追加] を選択します。
変換ロジックを追加する
クラス ファイルの内容を次のコードに置き換えて、ファイルを保存します。 PhonewordTranslator
クラスの静的メソッド ToNumber
は、英数字テキストから通常の数値式の電話番号に番号を変換します。
using System.Text;
namespace Core;
public static class PhonewordTranslator
{
public static string ToNumber(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
return null;
raw = raw.ToUpperInvariant();
var newNumber = new StringBuilder();
foreach (var c in raw)
{
if (" -0123456789".Contains(c))
newNumber.Append(c);
else
{
var result = TranslateToNumber(c);
if (result != null)
newNumber.Append(result);
// Bad character?
else
return null;
}
}
return newNumber.ToString();
}
static bool Contains(this string keyString, char c)
{
return keyString.IndexOf(c) >= 0;
}
static readonly string[] digits = {
"ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"
};
static int? TranslateToNumber(char c)
{
for (int i = 0; i < digits.Length; i++)
{
if (digits[i].Contains(c))
return 2 + i;
}
return null;
}
}
UI を作成する
Phoneword プロジェクトで MainPage.xaml ファイルを開きます。
ScrollView
コントロールとその内容を削除し、ContentPage
コントロールだけを残します。<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Phoneword.MainPage"> </ContentPage>
ContentPage に、垂直方向の、間隔が 15 単位でパディングが 20 単位の
VerticalStackLayout
コントロールを追加します。<ContentPage ... > <VerticalStackLayout Spacing="15" Padding="20"> </VerticalStackLayout> </ContentPage>
StackLayout に
Label
コントロールを追加します。<ContentPage ... > <VerticalStackLayout ...> <Label Text = "Enter a Phoneword" FontSize ="20"/> </VerticalStackLayout> </ContentPage>
StackLayout に
Entry
コントロールを、ラベルの下に追加します。Entry
コントロールは、ユーザーがデータを入力できるテキスト ボックスを提供します。 このコードでは、プロパティx:Name
がコントロールに名前を付けます。 このコントロールは、後でアプリのコードで参照します。<ContentPage ... > <VerticalStackLayout ...> <Label .../> <Entry x:Name = "PhoneNumberText" Text = "1-555-NETMAUI" /> </VerticalStackLayout> </ContentPage>
VerticalStackLayout に 2 つの
Button
コントロールを、Entry コントロールの後に追加します。 どちらのボタンもこの時点では何も行わず、2 つ目は最初は無効になっています。 次のタスクで、これら 2 つのボタンのClicked
イベントを処理するコードを追加します。<ContentPage ... > <VerticalStackLayout ...> <Label .../> <Entry ... /> <Button x:Name = "TranslateButton" Text = "Translate" Clicked = "OnTranslate"/> <Button x:Name = "CallButton" Text = "Call" IsEnabled = "False" Clicked = "OnCall"/> </VerticalStackLayout> </ContentPage>
[TranslateButton] ボタン タップに応答する
ソリューション エクスプローラー ウィンドウで、MainPage.xaml エントリを展開し、MainPage.xaml.cs 分離コード ファイルを開きます。
MainPage
クラスで、count
変数とOnCounterClicked
メソッドを削除します。 クラスは次のようになります。namespace Phoneword; public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } }
translatedNumber
文字列変数と次のOnTranslate
メソッドをMainPage
クラスに、コンストラクターの後に追加します。 このOnTranslate
メソッドは、Entry
コントロールのText
プロパティから電話番号を取得し、それを前に作成したPhonewordTranslator
クラスの静的なToNumber
メソッドに渡します。public partial class MainPage : ContentPage { ... string translatedNumber; private void OnTranslate(object sender, EventArgs e) { string enteredNumber = PhoneNumberText.Text; translatedNumber = Core.PhonewordTranslator.ToNumber(enteredNumber); if (!string.IsNullOrEmpty(translatedNumber)) { // TODO: } else { // TODO: } } }
Note
次の手順では、このコードの不足している TODO ビットを入力します。
OnTranslate
メソッドに、正常に変換された電話番号を追加するように [発信] ボタンのText
プロパティを変更するコードを追加します。 translatedNumber フィールドに格納した値を使用できます。 さらに、成功した変換に基づいてボタンを有効または無効にします。 たとえば、TranslateNumber
が null 値を返した場合はボタンを無効にし、成功した場合は有効にします。private void OnTranslate(object sender, EventArgs e) { string enteredNumber = PhoneNumberText.Text; translatedNumber = Core.PhonewordTranslator.ToNumber(enteredNumber); if (!string.IsNullOrEmpty(translatedNumber)) { CallButton.IsEnabled = true; CallButton.Text = "Call " + translatedNumber; } else { CallButton.IsEnabled = false; CallButton.Text = "Call"; } }
CallButton ボタンのイベント メソッドを作成する
MainPage
クラスの末尾にOnCall
イベント処理メソッドを追加します。 このメソッドは非同期操作を使用するため、async
とマークします。public partial class MainPage : ContentPage { ... async void OnCall(object sender, System.EventArgs e) { } }
OnCall
メソッドで、Page.DisplayAlert メソッドを使用して、ユーザーに番号をダイヤルするかどうかを確認するプロンプトを表示します。DisplayAlert
に対するパラメーターは、タイトル、メッセージ、[承諾] および [キャンセル] ボタンのテキストに使用される 2 つの文字列です。 これは、ダイアログ ボックスを閉じるために [承諾] ボタンが押されたかどうかを示すブール値を返します。async void OnCall(object sender, System.EventArgs e) { if (await this.DisplayAlert( "Dial a Number", "Would you like to call " + translatedNumber + "?", "Yes", "No")) { // TODO: dial the phone } }
アプリケーションをテストする
Visual Studio ツールバーで Windows Machine プロファイルを選択し、デバッグを開始します。
[変換] ボタンをタップして、既定のテキストを有効な電話番号に変換します。 [通話] ボタンのキャプションは [通話 1-555-6386284] に変化するはずです。
[通話] ボタンをタップします。 操作の確認を求めるプロンプトが表示されることを確認します。 このため、 [いいえ] を選択します。
Visual Studio に戻り、デバッグを停止します。
電話番号をダイヤルする
MainPage.xaml.cs 分離コード ファイルで、OnCall メソッドを編集し、TODO コメントを次の
try/catch
ブロックに置き換えます。async void OnCall(object sender, System.EventArgs e) { if (await this.DisplayAlert( "Dial a Number", "Would you like to call " + translatedNumber + "?", "Yes", "No")) { try { if (PhoneDialer.Default.IsSupported) PhoneDialer.Default.Open(translatedNumber); } catch (ArgumentNullException) { await DisplayAlert("Unable to dial", "Phone number was not valid.", "OK"); } catch (Exception) { // Other error has occurred. await DisplayAlert("Unable to dial", "Phone dialing failed.", "OK"); } } }
Microsoft.Maui.ApplicationModel.Communication 名前空間の PhoneDialer クラスでは、Windows、Android、iOS (および iPadOS)、macOS プラットフォームの電話ダイヤル機能 (およびその他) を抽象化します。 静的 Open メソッドは、電話ダイヤラーを使用して、パラメーターとして指定された番号を呼び出そうとします。
次の手順では、Android アプリケーション マニフェストを更新して Android で電話ダイヤラーを使用できるようにする方法を示します。 Windows、iOS、MacCatalyst のアプリケーションは、オペレーティング システムに応じてマニフェストで異なる機能を指定する点を除いて、同じ一般原則に従います。
ソリューション エクスプローラー ウィンドウで、[プラットフォーム] フォルダー、[Android] フォルダーの順に展開し、AndroidManifest.xml ファイルを右クリックして、[プログラムから開く]>[自動エディター セレクター (XML)] の順に選択します。 [OK] を選択します。
manifest ノード内に次の XML スニペットを、このノードの既存のコンテンツの後に追加します。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> ... <queries> <intent> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel"/> </intent> </queries> </manifest>
ファイルを保存します。
Visual Studio ツールバーで、Android Emulators/Pixel 3a - API 30 (またはそれと同等の) プロファイルを選択し、デバッグを開始します。
エミュレーターにアプリが表示されたら (これには数分かかる場合があります)、電話番号を入力して (または既定値をそのまま使用して) [変換] を選択し、[発信] を選択します。
[番号をダイヤルする] アラートで [はい] を選択します。 アプリで指定した番号で Android 電話ダイヤラーが表示されることを確認します。
Visual Studio に戻り、デバッグを停止します。
まとめ
この演習では、ページおよびビューを使用してアプリケーションにカスタム UI を追加しました。 また、Android で利用可能なプラットフォーム固有の API を使用して電話をかけるためのサポートも追加しました。