連載
» 2013年08月02日 18時00分 公開

TwilioならLINEみたいな通話機能をカンタン実装できる!Androidアプリちょい足し開発レシピ(3)(3/4 ページ)

[諏訪悠紀,アンダースコア]

認証・発信用のActivityの実装

 まずは、レイアウトの作成ですが、以下のウィジェットを配置します。

  • Twilioに登録するクライアント名を入力するためのEditText
  • Twilioアプリケーションサーバに接続する処理を実行するためのButton
  • 電話をかける相手のクライアント名を入力するためのEditText
  • 電話をかける(Twilioに接続する)処理を実行するためのButton

 以下のような画面レイアウトを作りましょう(レイアウトの作成方法は割愛します)。

図3 認証・発信用のActivityのレイアウト

 次に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.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。