はじめまして、Arganoの小副川です。
この記事では、AndroidでTelecomフレームワークを利用して電話を発信するアプリの実装方法について紹介します。
言語にはJava、IDEにAndroid Studioを利用する前提で進めていきます。Android Studioの環境構築に関しては触れておりません。
Telecomフレームワークとは
Telecomは、音声通話やビデオ通話の状態をAndroid OSに伝える役割を担っており、他の通話アプリと通話状態が競合しないように管理するためのフレームワークです。
今回は、Telecomフレームワークが提供する TelecomManager クラスの placeCall メソッドを使って電話を発信するだけのシンプルなアプリを実装していきます。
プロジェクトの作成
Android Studioに用意されている[Empty Activity]テンプレートを利用してプロジェクトを作成します。
- File>New>New Project を選択します。
 - [Phone and Tablet]タブの[Empty Activity]を選択して、[Next]をクリックします。
 - [Name]にプロジェクト名を入力、今回は 
CallAppとでもしておきます。 - [Package name]と[Save location]はそのままにします。
 - [Language]は[Java]を選択します。
 - [Minimum SDK]は[API 30]を選択、こちらは開発環境によって適宜変更してください。
 - [Finish]をクリックして、Gradleのビルドが終わるのを待ちましょう。
 
EditTextとButtonの配置
プロジェクトの作成が完了しましたので、電話番号の入力と発信に使うボタンの準備に取り掛かります。
res/values/strings.xml を開き、画面に表示させる文字列を記述していきましょう。
<string name="phone_input">電話番号入力</string>
<string name="call_button">発信</string>
次に、res/layout/activity_main.xml を開きます。レイアウトエディタを使用せずにコーディングしていきますので、[Design]が選択されている場合は[Code]に切り替えてください。
androidx.constraintlayout.widget.ConstraintLayout とその中身は使用しませので削除しましょう。代わりに、 LinearLayout の中へ EditText と Button を配置してきます。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="20dp"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:orientation="vertical">
    <EditText
        android:id="@+id/phone_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/phone_input"
        android:inputType="phone" />
    <Button
        android:id="@+id/call_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/call_button"
        android:onClick="call" />
</LinearLayout>
LinearLayout の android:orientation はウィジェットを配置していく方向を指定します。vertical として縦方向に配置していきましょう。 android:padding はお好みで。
EditText の android:hint に "@string/phone_input" を設定すると、先ほど strings.xml に記述した文字列をプレイスホルダーに指定することができます。Button は android:text に "@string/call_button" を記述して、こちらも表示させたい文字列と紐付けを行ってください。
電話番号の入力を受け付けたいので、EditText の android:inputType を phone として数字キーパッドをポップアップさせます。
Button の onClick に設定されているのは、後ほど発信機能を実装するメソッド名です。
この状態でビルドして、実機で確認をしてみましょう。お持ちのAndroid端末の開発者モードをオンにして(開発者モードをオンにする方法についてはこちらをご参照ください)、ツールバーの[Run]ボタンをクリックします。
ビルドが終わって、テキストボックスとボタンが縦に表示されていれば上手くいっています!
PermissionとServiceの追加
電話の発信は、Android OSに依存した機能です。こちらを利用するためには権限が必要なので、manifests/AndroidManifest.xml に CALL_PHONE 権限を使用するための宣言をしましょう。
<uses-permission android:name="android.permission.CALL_PHONE" />
placeCallメソッドによる発信機能の実装
準備が整いましたので、本題の発信機能を実装していきましょう!
java/{your_package_name}/MainActivity.java を開き、call メソッドを宣言します。
public class MainActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
  public void call(View view) {
  }
}
次に、placeCall メソッドを呼び出すための TelecomManager のインスタンスをcall メソッド内に作成してください。
TelecomManager manager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
placeCallメソッドには通話先の電話番号とその通話がどのような形式であるかを知らせる必要があるため、引数に渡すためのオブジェクトを宣言していきます。
第一引数には Uri オブジェクトを渡します。EditText に入力された電話番号を Uri 形式( "tel: {phoneNumber}" )に変換していきましょう。
EditText input = findViewById(R.id.phone_input);
Uri uri = Uri.fromParts("tel", input.getText().toString(), null);
findViewById メソッドに activity_main.xml の android:id へ設定したidを指定することで、EditText 内の電話番号を取得することができます。
第二引数には、Bundleを渡します。Bundleとは、Androidのアプリ、ページ間でデータをやりとりする際に利用するオブジェクトです。こちらには、スピーカー通話であることをAndroid OSに伝えるステータスを追加しておきます。
Bundle extras = new Bundle();
extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true);
manager から placeCall メソッドを呼び出し、先ほど宣言した Uri と Bundleを渡してください。
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
  return;
}
manager.placeCall(uri, extras);
placeCall メソッドは、実行前に電話権限が付与されているかの確認が必要となります。if文を追加して権限が無い場合に処理が停止するようにしましょう。
これで発信アプリの実装が完了しましたので、[Run]から実機にビルドします。ビルド完了後、設定アプリの[アプリと通知]から CallApp を選択して、通話権限を付与してください。
アプリ画面から任意の電話番号を入力して発信ボタンをタップし、Android OSの通話画面が表示されれば成功です!
今回の実装は発信機能のみだったので触れませんでしたが、通話中や着信の機能を追加する場合は ConnectionService というServiceクラスを使ってAndroid OSと通話状態の伝達をする必要があります。興味がありましたら、こちらから調べてみてください。
お疲れ様でした!
