TwilioならLINEみたいな通話機能をカンタン実装できる!:Androidアプリちょい足し開発レシピ(3)(3/4 ページ)
AndroidアプリにさまざまなWebサービスやライブラリを「ちょい足し」することで魅力的なアプリに大変身させる方法を紹介する連載。今回は、クラウド電話APIサービスTwilioを使った音声通話アプリの作り方を紹介。自作アプリにコミュニケーション機能を追加してみよう。
認証・発信用のActivityの実装
まずは、レイアウトの作成ですが、以下のウィジェットを配置します。
- Twilioに登録するクライアント名を入力するためのEditText
- Twilioアプリケーションサーバに接続する処理を実行するためのButton
- 電話をかける相手のクライアント名を入力するためのEditText
- 電話をかける(Twilioに接続する)処理を実行するためのButton
以下のような画面レイアウトを作りましょう(レイアウトの作成方法は割愛します)。
次にActivityを以下のように実装します。
package jp.classmethod.android.sample.twiliophone; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.content.Loader; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import com.twilio.client.Device; import com.twilio.client.Twilio; public class MainActivity extends FragmentActivity implements OnClickListener, Twilio.InitListener { private static final String TAG = HelloTwilioActivity.class.getSimpleName(); private Device mDevice; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hello_twilio); // Connectボタン findViewById(R.id.connect).setOnClickListener(this); findViewById(R.id.dial).setOnClickListener(this); // Twilioクライアントを初期化する Twilio.initialize(getApplicationContext(), this); } /* * Twilio.InitListener method */ @Override public void onInitialized() { Log.d(TAG, "Twilioクライアントの初期化が完了しました"); } @Override public void onError(Exception e) { Log.e(TAG, "エラーが発生しました:" + e.getLocalizedMessage()); } @Override public void onClick(View v) { switch (view.getId()) { case R.id.connect: // TwiMLアプリサーバに接続する処理 break; case R.id.dial: // Twilioに接続する処理 break; } } }
Twilio.initializeメソッドで初期化するところなどは前回と同様です。Twilio.InitListenerのonInitialized()メソッドが呼び出されたらTwilio Client SDKが使える状態になります。Twilioアプリケーションサーバに接続する処理を実行するためのButton電話をかける(Twilioに接続する)処理を実行するためのButtonにOnClickListenerをセットし、onClickメソッドでそれぞれの処理が実行できるような形まで実装します。
Deviceクラスを取得する非同期クラスを実装しましょう。AsyncTaskLoaderを継承した「DeviceLoader」クラスを新規作成し、以下のように実装します。
package jp.classmethod.android.sample.twiliophone; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.support.v4.content.AsyncTaskLoader; import android.util.Log; import com.twilio.client.Device; import com.twilio.client.Twilio; public class DeviceLoader extends AsyncTaskLoader<Device> { private static final String TAG = DeviceLoader.class.getSimpleName(); private String mClientName; public DeviceLoader(Context context, String clientName) { super(context); mClientName = clientName; } @Override public Device loadInBackground() { try { // ケイパビリティトークンを取得する String url = "http://YOUR-APP-NAME.herokuapp.com/auth?name=" + mClientName; HttpClient httpClient = new DefaultHttpClient(); HttpGet get = new HttpGet(url); HttpResponse res = httpClient.execute(get); HttpEntity entity = res.getEntity(); String token = EntityUtils.toString(entity); Log.d(TAG, "トークン:" + token); // Twilioにデバイスを登録する Device device = Twilio.createDevice(token, null); // 着信を受けるためのIntentを生成してセットする Intent intent = new Intent(getContext(), IncomingActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); device.setIncomingIntent(pendingIntent); return device; } catch (Exception e) { Log.e(TAG, "エラー:" + e.getLocalizedMessage()); } return null; } }
Deviceクラスを取得するにはケイパビリティトークンが必要ですので、TwiMLアプリサーバで作成した認証用APIを呼び出し、取得します。このときリクエストパラメータにクライアント名を渡す必要がありますが、EditTextで入力されたクライアント名が受け取れるよう、コンストラクタ引数に追加しておきます。
Twilio.createDevice()メソッドを呼び出し、Deviceインスタンスを取得します。引数には認証用APIから取得したケイパビリティトークンを渡します。このDeviceインスタンスを使ってTwilioに接続(電話の発信)することになります。
DeviceインスタンスのsetIncomingIntent()メソッドを使って、着信があったときに呼び出されるPendingIntentをセットします。PendingIntentから呼び出されるActivityはIncomingActivityをセットしていますが、このクラスは後で実装します。
以上でDeviceLoaderクラスの実装が終わりました。
続いて、MainActivityの実装に戻り、接続用のボタンと発信用のボタンをタップしたときの処理を実装しましょう。
@Override public void onClick(View view) { switch (view.getId()) { // Twilioに登録する case R.id.connect: // 入力されたクライアント名をパラメータに設定する EditText clientName = (EditText) findViewById(R.id.client_name); Bundle bundle = new Bundle(); bundle.putString("name", clientName.getText().toString()); // TwilioPhoneLoaderを呼び出す getSupportLoaderManager().initLoader(TWILIO_PHONE_LOADER, bundle, this); break; } // 電話をかける case R.id.dial: // 入力されたクライアント名をパラメータに設定する EditText to = (EditText) findViewById(R.id.dial_name); HashMap<String, String> params = new HashMap<String, String>(); params.put("name", to.getText().toString()); // 電話をかける mDevice.connect(params, null); break; } } /* * LoaderCallbacks method */ @Override public Loader<Device> onCreateLoader(int id, Bundle bundle) { DeviceLoader loader = new DeviceLoader(getApplicationContext(), bundle.getString("name")); loader.forceLoad(); return loader; } @Override public void onLoadFinished(Loader<Device> loader, Device device) { Log.d(TAG, "デバイスの準備が完了しました"); mDevice = device; getSupportLoaderManager().destroyLoader(TWILIO_PHONE_LOADER); } @Override public void onLoaderReset(Loader<Device> loader) { }
接続用ボタン(ここでは「connect」というIDのボタン)をタップしたときは、DeviceLoaderを呼び出すように実装します。DeviceLoaderのコールバックを受け取るためにLoaderCallbacksを実装し、onCreateLoader()でDeviceLoaderをインスタンス化し、非同期処理を実行します。onLoadFinished()でDeviceインスタンスを受け取り、メンバ変数として保持します。
発信用ボタン(ここでは「dial」というIDのボタン)をタップしたときは、Deviceインスタンスのconnect()メソッドを呼び出し、Twilioに接続します。ここでTwilioに接続することで、Twilio側ではTwiMLアプリのTwiMLを返すAPIを呼び出し、TwiMLに記載された命令を実行してくれます。第1引数に渡しているHashMapインスタンスはリクエストパラメータです。TwiMLを返すAPIを呼び出すときのリクエストパラメータとして使われます。
以上でTwilioに認証しDeviceインスタンスを受け取る処理、そしてDeviceインスタンスを使ってTwilioに接続する処理の実装が終わりました。
Copyright © ITmedia, Inc. All Rights Reserved.