2011年1月27日木曜日



Android2.3で搭載されたNFCの、P2Pモードについて調べました。


P2Pモードとは、NFCデバイス同士がP2P通信を行うためのモードです。このモードで動作するNFCデバイス同士は、Bluetoothのペアリングのような煩雑な手順を経ずにデータの送受信が可能になります。


Android2.3のNFCはデフォルトで、ICカードリーターとして振舞うリーダーモードとして動作しています。そのため、P2Pモードとして動作するようにNFCのサービスに指示する必要があります。


しかし、結論から言うとタイトルの通り、Android2.3はP2Pモードになることができません。次のAOSPのコミットメッセージのとおり、リリース段階でP2Pモードは無効になってしまったようです。









ざんねん。。








文責:技術部 ますい





Android 2.3 のNFCはP2Pモードが使えない



Android2.3で搭載されたNFCの、P2Pモードについて調べました。


P2Pモードとは、NFCデバイス同士がP2P通信を行うためのモードです。このモードで動作するNFCデバイス同士は、Bluetoothのペアリングのような煩雑な手順を経ずにデータの送受信が可能になります。


Android2.3のNFCはデフォルトで、ICカードリーターとして振舞うリーダーモードとして動作しています。そのため、P2Pモードとして動作するようにNFCのサービスに指示する必要があります。


しかし、結論から言うとタイトルの通り、Android2.3はP2Pモードになることができません。次のAOSPのコミットメッセージのとおり、リリース段階でP2Pモードは無効になってしまったようです。









ざんねん。。








文責:技術部 ますい





2011年1月11日火曜日



f:id:bs-android:20110107175909j:image,w400,h300
[Nexus SからHTC Desireに電話してる様子]


Android2.3(gingerbread)で追加されたAPIの一つであるSIP APIを試してみました。
Android SDK 2.3に同梱されているSipDemoというプロジェクトを使ってどの様な手順でSIP通話を実現しているか解説します。


実施環境


発信側:
  端末:Nexus S
  アプリ:SipDemo


着信側:
  端末:HTC Desire (android2.2)
  アプリ:Sipdroid version 2.0.1 beta





準備


まずSIPで通話する為にSIPアカウントを取得しました。Android2.3ではSIP通話の為の各種APIを提供してくれますが、SIPアカウントやSIPプロバイダまでは提供してくれません。いっそGoogleがSIPプロバイダ買収して統合しちゃってくれるとうれしいんですが・・・。
今回はiptel.orgという無料のSIPプロバイダを利用しました。
ここで発信、着信用の二つのアカウントを作成しました。iptel.orgのページの下部の「Subscribe!」から新規アカウントの作成ができます。





通話してみる


とりあえず通話をしてみます。
SipDemoをビルドしてNexus Sにインストールし、起動すると以下の様な画面が現れます。
f:id:bs-android:20110110171031p:image,w320,h480


自分のSIPアカウントを設定していない場合は以下のダイアログが表示されます。
OKを選択するとアカウント設定画面が開きます。
f:id:bs-android:20110110163805p:image,w320,h480


アカウント設定画面で、SIPアカウント、パスワード、SIPプロバイダのドメインを設定します。
f:id:bs-android:20110110163804p:image,w320,h480


設定が完了すると、SIPプロバイダにREGISTERを試みます。成功すると、「Ready」の文字列が表示されます。
f:id:bs-android:20110110163803p:image,w320,h480


「Ready」の状態でメニューを表示し、「Call someone」を選択します。
f:id:bs-android:20110110163802p:image,w320,h480


発信する相手先を入力するダイアログが表示されます。
ここに相手のSIPURI(例:moge@sip.hoge.jp)を入力し、「OK」ボタンを押下すると相手にINVAITEします。
f:id:bs-android:20110110163801p:image,w320,h480


通話に成功した場合、マイクをタッチしている間、自分の声を相手に送信します。


f:id:bs-android:20110110164442p:image,w320,h480








SipDemoおよびAPIの説明


■SipDemoの場所
 「Android SDK Samples for Android API 9, revision 1」がインストールされていれば下記の場所にプロジェクトがあるはずです。


    <android-sdk>/samples/android-9/SipDemo





■SipDemoの構成
 SipDemoのファイル構成です。XMLファイル類は特に気にするようなものは無かったので割愛します。


  IncomingCallReceiver.java //着信を受けるBroadcastReceiver
  SipSettings.java //SIPプロファイルの設定を行うPreferenceActivity
  WalkieTalkieActivity.java //SIPプロファイルの初期化、REGISTER、発信等を行うActivity





■AndroidManifest.xml
 AndroidでSIPを利用する場合、AndroidManifest.xmlに以下のuses-permissionを追加してあげる必要があります。


  android.permission.USE_SIP
  android.permission.INTERNET
  android.permission.ACCESS_WIFI_STATE
  android.permission.WAKE_LOCK
  android.permission.RECORD_AUDIO
  android.permission.MODIFY_AUDIO_SETTINGS


 SipDemoではこのうち「android.permission.MODIFY_AUDIO_SETTINGS」の設定が抜けていますので追記してやる必要があります。「android.permission.MODIFY_AUDIO_SETTINGS」が無くても動作しますが、音声設定周りが無効になってしまいます。





■利用するクラス
 SIP通話を行うために利用するクラスです。以下のクラスを使うだけでSIP通話を実現する事ができます。


  android.net.sip.SipManager       //SIPプロバイダへのREGISTERや発信、着信を管理するクラス
  android.net.sip.SipProfile        //自分のSIPプロファイル
  android.net.sip.SipRegistrationListener //SIPプロバイダにREGISTERする際のリスナ
  android.net.sip.SipAudioCall      //SIP通話の音声を管理する
  android.net.sip.SipAudioCall.Listener  //SIP通話の確立や切断、エラー等のリスナ
  android.net.sip.SipException      //SIP周りの例外








発信までの手順


 発信の処理はWalkieTalkieActivity.javaで行っています。




  1. SipManagerを作成する

  2. SipProfileを作成する

  3. SipManager#open(String, SipRegistrationListener)でSIPプロバイダにREGISTERする

  4. SipManager#makeAudioCall(String ,String, SipAudioCall.Listener, int)で相手先に電話をかける

  5. SipAudioCall.Listener#onCallEstablished(SipAudioCall)で音声通話を開始する





1.SipManagerを作成する

 SipManagerはWalkieTalkieActivity.javaの106行目、initializeManager()で作成しています。
 単純にメンバ変数managerがnullの場合SipManager#newInstance(Context)を呼び出しているだけです。



public void initializeManager() {
if(manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}








2.SipProfileを作成する

 WalkieTalkieActivity.javaの138行目、initializeLocalProfile()内でSipProfileを作成しています。
 SipProfileの作成はSipProfile.Builderクラスを使って行います。コンストラクタにSIPプロバイダで取得したアカウント名、SIPプロバイダのドメイン名を設定します。(例:hoge@sip.moge.jpの場合、「hoge」がアカウント名で「sip.moge.jp」がドメイン名となります。)
 BuilderをnewしたあとsetPassword(String)でアカウントのパスワードをセットします。最後にSipProfile.Builder#build()を呼び出しSipProfileを作成します。



SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
me = builder.build(); //meはメンバ変数。SipProfile型








3.SipManager#open(SipProfile, String, SipRegistrationListener)でSIPプロバイダにREGISTERする

 WalkieTalkieActivity.javaの142行目、initializeLocalProfile()内でSipProfileを作成した後、SipManager#openでSIPプロバイダに対してREGISTERを行います。
 openする際にSipRegistrationListenerでREGISTERの結果を受け取ります。何故かリスナのセットはSipManager#openを呼び出した後にしろ、との事。
 SipRegistrationListenerは以下の3つのコールバックを持ちます。




  • public void onRegistering(String localProfileUri)                       //REGISTER中

  • public void onRegistrationDone(String localProfileUri, long expiryTime)            //REGISTER成功

  • public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage)  //REGISTER失敗


 SipDemoではこれらのコールバック時に、画面に各種状態の文字列を表示させています。
 SipManager#openをする際にPendingIntentをセットしていますが、これは着信の為に利用します。説明は後ほどします。



Intent i = new Intent();i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);


// This listener must be added AFTER manager.open is called,
// Otherwise the methods aren't guaranteed to fire.

manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
}

public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
}

public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings.");
}
});









4.SipManager#makeAudioCall(String ,String, SipAudioCall.Listener, int)で相手先に電話をかける

 WalkieTalkieActivity.javaの197行目、initiateCall()内でSipManager#makeAudioCall(String, String, SipAudioCall.Listener, int)を呼び出します。引数は自分のSIPURI, 相手のSIPURI,SipAudioCall.Listener,タイムアウト秒です。
 SipAudioCall.Listenerはリスナという名前のくせにクラスです。コールバックの種類が結構多いのでinterfaceだと煩雑だと考えたのでしょうか?必要なコールバックだけオーバーライドして利用します。SipDemoでは相手が着信後200 OKを返し、通信が確立された際に呼び出されるonCallEstablished(SipAudioCall)と、通話を切断した場合に呼び出されるonCallEnded(SipAudioCall)をオーバーライドしています。



SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// Much of the client's interaction with the SIP Stack will
// happen via listeners. Even making an outgoing call, don't
// forget to set up a listener to set things up once the call is established.
@Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}

@Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Ready.");
}
};

call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);









5.SipAudioCall.Listener#onCallEstablished(SipAudioCall)で音声通話を開始する

 WalkieTalkieActivity.javaの202行目、SipAudioCall.Listener#onCallEstablished(SipAudioCall)でSipAudioCall#startAudio()を呼び出し音声通話を開始します。
 SipAudioCall#setSpeakerMode(boolean)にtrueをセットしています。これでハンズオンの状態で通話が開始されます。また、SipAudipCall#toggleMute()を呼び出しています。これで自分の音声はミュートされます。このミュートはタッチ処理の中で「タッチされている間だけオン」といった感じで実装されています。普通の電話の様な動作にしたい場合はcall.toggleMute()の行とタッチイベントの処理を削除するだけで実現できます。



@Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}











着信-通話までの手順


 着信はIncomingCallReceiver.javaで行います。IncomingCallReceiverはBroadcastReceiverを継承しており、WalkieTalkieActivityが実行されている間だけ着信を受けます。




  1. IncomingCallReceiverをシステムに登録する

  2. SipManagerに着信時に実行されるPendingIntentを登録する

  3. SipManagerを作成する

  4. SipProfileを作成する

  5. SipManager#open(String, SipRegistrationListener)でSIPプロバイダにREGISTERする

  6. IncomingCallReceiver#onReceive(Context, Intent)で通話を開始する





1.IncomingCallReceiverをシステムに登録する

 WalkieTalkieActivity.javaの69行目、onCreate(Bundle)内でIncomingCallReceiverをシステムに登録します。
 IntentFilterには"android.SipDemo.INCOMING_CALL"を指定しています。"android.SipDemo.INCOMING_CALL"のアクションを持つIntentがBroadcastされた場合に受け取る、という事です。



// Set up the intent filter. This will be used to fire an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);











2.SipManagerに着信時に実行されるPendingIntentを登録する

 WalkieTalkieActivity.javaの142行目、initializeLocalProfile()内でPendingIntentを作成し、SipManager#openで登録しています。このPendingIntentは着信があった場合に実行されます。
 SipDemoでは"android.SipDemo.INCOMING_CALL"のアクションをBroadcastするPendingIntentを登録しています。このアクションはIncomingCallReceiverをシステムに登録する際に指定したIntentFilterと一致します。



Intent i = new Intent();i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);





3.SipManagerを作成する

発信と同じなので省略


4.SipProfileを作成する

発信と同じなので省略


5.SipManager#open(String, SipRegistrationListener)でSIPプロバイダにREGISTERする

発信と同じなので省略





6.IncomingCallReceiver#onReceive(Context, Intent)で通話を開始する

 IncomingCallReceiver.javaの37行目,onReceive(Context, Intent)で着信の処理を行っています。
ContextをWalkieTalkieActivityにキャストし、SipManager#takeAudioCall(Intent, SipAudioCall.Listener)を呼び出しています。SipManager#takeAudioCallを実行したら、次にSipAudioCall.Listener#onRinging(SipAudioCall, SipProfile)が呼び出されます。おそらく内部で100 TRYING、180 RINGINGを発信側に返してonRinging(SipAudioCall, SipProfile)を呼び出しているのだと思います。ここでSipAudioCall#answerCall(int)を呼び出します。javadocを読んでもいまいち動作が不明ですが、200 OKを返しているのでは無いかと思います。onRingingの後にincamingCall.answerCall(30)を実行しています。未確認ですが、この二回目のanswerCallは不要なんじゃないかなーと思います。
 その後SipAudioCall#startAudio()で通話を開始しています。
 wtActivity.call = incomingCall;でWalkieTalkieActivityのメンバ変数にSipAudioCallを設定していますが、WalkieTalkieActivityを終了したり、メニューの「End Current Call」を選択した時にSipAudioCall#endCall()を実行させる為です。



@Override
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {

SipAudioCall.Listener listener = new SipAudioCall.Listener() {
@Override
public void onRinging(SipAudioCall call, SipProfile caller) {
try {
call.answerCall(30);
} catch (Exception e) {
e.printStackTrace();
}
}
};

WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;

incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
incomingCall.answerCall(30);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
if(incomingCall.isMuted()) {
incomingCall.toggleMute();
}

wtActivity.call = incomingCall;

wtActivity.updateStatus(incomingCall);

} catch (Exception e) {
if (incomingCall != null) {
incomingCall.close();
}
}
}












最後に


SIPに関する面倒なほとんどの処理をSIP APIが抽象化してくれました。
上記で説明した手順だけでSIP通話が行えます。SIP APIを使って、例えばAccountManagerに登録されているGMailのアドレスから自動的にSIPアカウント払い出しを行ってすぐ通話できるアプリ、とか割と簡単に作成できそうですね。



文責:技術部 八木 俊広 (新人/Androidアプリケーション技術者認定試験ベーシック合格(笑)/品川)





概説SipDemo(Android2.3 SIP APIを試す)



f:id:bs-android:20110107175909j:image,w400,h300
[Nexus SからHTC Desireに電話してる様子]


Android2.3(gingerbread)で追加されたAPIの一つであるSIP APIを試してみました。
Android SDK 2.3に同梱されているSipDemoというプロジェクトを使ってどの様な手順でSIP通話を実現しているか解説します。


実施環境


発信側:
  端末:Nexus S
  アプリ:SipDemo


着信側:
  端末:HTC Desire (android2.2)
  アプリ:Sipdroid version 2.0.1 beta





準備


まずSIPで通話する為にSIPアカウントを取得しました。Android2.3ではSIP通話の為の各種APIを提供してくれますが、SIPアカウントやSIPプロバイダまでは提供してくれません。いっそGoogleがSIPプロバイダ買収して統合しちゃってくれるとうれしいんですが・・・。
今回はiptel.orgという無料のSIPプロバイダを利用しました。
ここで発信、着信用の二つのアカウントを作成しました。iptel.orgのページの下部の「Subscribe!」から新規アカウントの作成ができます。





通話してみる


とりあえず通話をしてみます。
SipDemoをビルドしてNexus Sにインストールし、起動すると以下の様な画面が現れます。
f:id:bs-android:20110110171031p:image,w320,h480


自分のSIPアカウントを設定していない場合は以下のダイアログが表示されます。
OKを選択するとアカウント設定画面が開きます。
f:id:bs-android:20110110163805p:image,w320,h480


アカウント設定画面で、SIPアカウント、パスワード、SIPプロバイダのドメインを設定します。
f:id:bs-android:20110110163804p:image,w320,h480


設定が完了すると、SIPプロバイダにREGISTERを試みます。成功すると、「Ready」の文字列が表示されます。
f:id:bs-android:20110110163803p:image,w320,h480


「Ready」の状態でメニューを表示し、「Call someone」を選択します。
f:id:bs-android:20110110163802p:image,w320,h480


発信する相手先を入力するダイアログが表示されます。
ここに相手のSIPURI(例:moge@sip.hoge.jp)を入力し、「OK」ボタンを押下すると相手にINVAITEします。
f:id:bs-android:20110110163801p:image,w320,h480


通話に成功した場合、マイクをタッチしている間、自分の声を相手に送信します。


f:id:bs-android:20110110164442p:image,w320,h480








SipDemoおよびAPIの説明


■SipDemoの場所
 「Android SDK Samples for Android API 9, revision 1」がインストールされていれば下記の場所にプロジェクトがあるはずです。


    <android-sdk>/samples/android-9/SipDemo





■SipDemoの構成
 SipDemoのファイル構成です。XMLファイル類は特に気にするようなものは無かったので割愛します。


  IncomingCallReceiver.java //着信を受けるBroadcastReceiver
  SipSettings.java //SIPプロファイルの設定を行うPreferenceActivity
  WalkieTalkieActivity.java //SIPプロファイルの初期化、REGISTER、発信等を行うActivity





■AndroidManifest.xml
 AndroidでSIPを利用する場合、AndroidManifest.xmlに以下のuses-permissionを追加してあげる必要があります。


  android.permission.USE_SIP
  android.permission.INTERNET
  android.permission.ACCESS_WIFI_STATE
  android.permission.WAKE_LOCK
  android.permission.RECORD_AUDIO
  android.permission.MODIFY_AUDIO_SETTINGS


 SipDemoではこのうち「android.permission.MODIFY_AUDIO_SETTINGS」の設定が抜けていますので追記してやる必要があります。「android.permission.MODIFY_AUDIO_SETTINGS」が無くても動作しますが、音声設定周りが無効になってしまいます。





■利用するクラス
 SIP通話を行うために利用するクラスです。以下のクラスを使うだけでSIP通話を実現する事ができます。


  android.net.sip.SipManager       //SIPプロバイダへのREGISTERや発信、着信を管理するクラス
  android.net.sip.SipProfile        //自分のSIPプロファイル
  android.net.sip.SipRegistrationListener //SIPプロバイダにREGISTERする際のリスナ
  android.net.sip.SipAudioCall      //SIP通話の音声を管理する
  android.net.sip.SipAudioCall.Listener  //SIP通話の確立や切断、エラー等のリスナ
  android.net.sip.SipException      //SIP周りの例外








発信までの手順


 発信の処理はWalkieTalkieActivity.javaで行っています。




  1. SipManagerを作成する

  2. SipProfileを作成する

  3. SipManager#open(String, SipRegistrationListener)でSIPプロバイダにREGISTERする

  4. SipManager#makeAudioCall(String ,String, SipAudioCall.Listener, int)で相手先に電話をかける

  5. SipAudioCall.Listener#onCallEstablished(SipAudioCall)で音声通話を開始する





1.SipManagerを作成する

 SipManagerはWalkieTalkieActivity.javaの106行目、initializeManager()で作成しています。
 単純にメンバ変数managerがnullの場合SipManager#newInstance(Context)を呼び出しているだけです。



public void initializeManager() {
if(manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}








2.SipProfileを作成する

 WalkieTalkieActivity.javaの138行目、initializeLocalProfile()内でSipProfileを作成しています。
 SipProfileの作成はSipProfile.Builderクラスを使って行います。コンストラクタにSIPプロバイダで取得したアカウント名、SIPプロバイダのドメイン名を設定します。(例:hoge@sip.moge.jpの場合、「hoge」がアカウント名で「sip.moge.jp」がドメイン名となります。)
 BuilderをnewしたあとsetPassword(String)でアカウントのパスワードをセットします。最後にSipProfile.Builder#build()を呼び出しSipProfileを作成します。



SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
me = builder.build(); //meはメンバ変数。SipProfile型








3.SipManager#open(SipProfile, String, SipRegistrationListener)でSIPプロバイダにREGISTERする

 WalkieTalkieActivity.javaの142行目、initializeLocalProfile()内でSipProfileを作成した後、SipManager#openでSIPプロバイダに対してREGISTERを行います。
 openする際にSipRegistrationListenerでREGISTERの結果を受け取ります。何故かリスナのセットはSipManager#openを呼び出した後にしろ、との事。
 SipRegistrationListenerは以下の3つのコールバックを持ちます。




  • public void onRegistering(String localProfileUri)                       //REGISTER中

  • public void onRegistrationDone(String localProfileUri, long expiryTime)            //REGISTER成功

  • public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage)  //REGISTER失敗


 SipDemoではこれらのコールバック時に、画面に各種状態の文字列を表示させています。
 SipManager#openをする際にPendingIntentをセットしていますが、これは着信の為に利用します。説明は後ほどします。



Intent i = new Intent();i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);


// This listener must be added AFTER manager.open is called,
// Otherwise the methods aren't guaranteed to fire.

manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
}

public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
}

public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings.");
}
});









4.SipManager#makeAudioCall(String ,String, SipAudioCall.Listener, int)で相手先に電話をかける

 WalkieTalkieActivity.javaの197行目、initiateCall()内でSipManager#makeAudioCall(String, String, SipAudioCall.Listener, int)を呼び出します。引数は自分のSIPURI, 相手のSIPURI,SipAudioCall.Listener,タイムアウト秒です。
 SipAudioCall.Listenerはリスナという名前のくせにクラスです。コールバックの種類が結構多いのでinterfaceだと煩雑だと考えたのでしょうか?必要なコールバックだけオーバーライドして利用します。SipDemoでは相手が着信後200 OKを返し、通信が確立された際に呼び出されるonCallEstablished(SipAudioCall)と、通話を切断した場合に呼び出されるonCallEnded(SipAudioCall)をオーバーライドしています。



SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// Much of the client's interaction with the SIP Stack will
// happen via listeners. Even making an outgoing call, don't
// forget to set up a listener to set things up once the call is established.
@Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}

@Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Ready.");
}
};

call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);









5.SipAudioCall.Listener#onCallEstablished(SipAudioCall)で音声通話を開始する

 WalkieTalkieActivity.javaの202行目、SipAudioCall.Listener#onCallEstablished(SipAudioCall)でSipAudioCall#startAudio()を呼び出し音声通話を開始します。
 SipAudioCall#setSpeakerMode(boolean)にtrueをセットしています。これでハンズオンの状態で通話が開始されます。また、SipAudipCall#toggleMute()を呼び出しています。これで自分の音声はミュートされます。このミュートはタッチ処理の中で「タッチされている間だけオン」といった感じで実装されています。普通の電話の様な動作にしたい場合はcall.toggleMute()の行とタッチイベントの処理を削除するだけで実現できます。



@Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}











着信-通話までの手順


 着信はIncomingCallReceiver.javaで行います。IncomingCallReceiverはBroadcastReceiverを継承しており、WalkieTalkieActivityが実行されている間だけ着信を受けます。




  1. IncomingCallReceiverをシステムに登録する

  2. SipManagerに着信時に実行されるPendingIntentを登録する

  3. SipManagerを作成する

  4. SipProfileを作成する

  5. SipManager#open(String, SipRegistrationListener)でSIPプロバイダにREGISTERする

  6. IncomingCallReceiver#onReceive(Context, Intent)で通話を開始する





1.IncomingCallReceiverをシステムに登録する

 WalkieTalkieActivity.javaの69行目、onCreate(Bundle)内でIncomingCallReceiverをシステムに登録します。
 IntentFilterには"android.SipDemo.INCOMING_CALL"を指定しています。"android.SipDemo.INCOMING_CALL"のアクションを持つIntentがBroadcastされた場合に受け取る、という事です。



// Set up the intent filter. This will be used to fire an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);











2.SipManagerに着信時に実行されるPendingIntentを登録する

 WalkieTalkieActivity.javaの142行目、initializeLocalProfile()内でPendingIntentを作成し、SipManager#openで登録しています。このPendingIntentは着信があった場合に実行されます。
 SipDemoでは"android.SipDemo.INCOMING_CALL"のアクションをBroadcastするPendingIntentを登録しています。このアクションはIncomingCallReceiverをシステムに登録する際に指定したIntentFilterと一致します。



Intent i = new Intent();i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);





3.SipManagerを作成する

発信と同じなので省略


4.SipProfileを作成する

発信と同じなので省略


5.SipManager#open(String, SipRegistrationListener)でSIPプロバイダにREGISTERする

発信と同じなので省略





6.IncomingCallReceiver#onReceive(Context, Intent)で通話を開始する

 IncomingCallReceiver.javaの37行目,onReceive(Context, Intent)で着信の処理を行っています。
ContextをWalkieTalkieActivityにキャストし、SipManager#takeAudioCall(Intent, SipAudioCall.Listener)を呼び出しています。SipManager#takeAudioCallを実行したら、次にSipAudioCall.Listener#onRinging(SipAudioCall, SipProfile)が呼び出されます。おそらく内部で100 TRYING、180 RINGINGを発信側に返してonRinging(SipAudioCall, SipProfile)を呼び出しているのだと思います。ここでSipAudioCall#answerCall(int)を呼び出します。javadocを読んでもいまいち動作が不明ですが、200 OKを返しているのでは無いかと思います。onRingingの後にincamingCall.answerCall(30)を実行しています。未確認ですが、この二回目のanswerCallは不要なんじゃないかなーと思います。
 その後SipAudioCall#startAudio()で通話を開始しています。
 wtActivity.call = incomingCall;でWalkieTalkieActivityのメンバ変数にSipAudioCallを設定していますが、WalkieTalkieActivityを終了したり、メニューの「End Current Call」を選択した時にSipAudioCall#endCall()を実行させる為です。



@Override
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {

SipAudioCall.Listener listener = new SipAudioCall.Listener() {
@Override
public void onRinging(SipAudioCall call, SipProfile caller) {
try {
call.answerCall(30);
} catch (Exception e) {
e.printStackTrace();
}
}
};

WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;

incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
incomingCall.answerCall(30);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
if(incomingCall.isMuted()) {
incomingCall.toggleMute();
}

wtActivity.call = incomingCall;

wtActivity.updateStatus(incomingCall);

} catch (Exception e) {
if (incomingCall != null) {
incomingCall.close();
}
}
}












最後に


SIPに関する面倒なほとんどの処理をSIP APIが抽象化してくれました。
上記で説明した手順だけでSIP通話が行えます。SIP APIを使って、例えばAccountManagerに登録されているGMailのアドレスから自動的にSIPアカウント払い出しを行ってすぐ通話できるアプリ、とか割と簡単に作成できそうですね。



文責:技術部 八木 俊広 (新人/Androidアプリケーション技術者認定試験ベーシック合格(笑)/品川)





2011年1月6日木曜日



某所からCES2011でAndroid3.0が爆発しているという話があったので、
関連すると思われるCES2011の動画を一通り見てみました。
結論から言うと、「最終的には3.0をのせるよ」というメーカーがほとんどで、
Android 3.0がどういったものかといった情報は今のところ特に得られませんでした。
CES2011と関連しているかは不明ですがGoogleが公式でアップしたとおぼしき動画があり、
そちらではかなり詳しくAndroid3.0に触れています(最下部にあります)。


Android3.0にするよ、と言っているメーカーの動画を紹介します。


Sony Ericsson Arc



D


Xperia arcの外観くるくる。
下記公式のブログでは2.3が乗ってるけどアップデートで3.0にする、と言っている模様
http://www.blogsonyericsson.com/2011/01/05/ces-2011-conoce-al-nuevo-sony-ericsson-xperia-arc/





Toshiba Honey Comb Tablet



D


東芝のタブレット端末の説明
動画ではAndroid2.2で動作している。
最終的には3.0をのせると言っている模様。





ASUS eeePad



D


10.1インチ版はAndroid3.0らしいが、
デモの人が持って写真とらせてるだけ。
12インチ版はWindows7。
モニタ部分を外したり付けたり





[Android 3.0]


Google公式の?Android OS3.0 Honey Comb紹介動画



D


元はGoogle公式の動画らしいですが、公開後すぐに削除されたようです。
有志らが閲覧した際に保存していた動画を再アップしている模様です。
CES2011と関連があるかは不明
ここではAndroid3.0について詳しく紹介がされています。
内容の説明についてはコチラを参照してください。
革新的なOSへ。Android 3.0(Honeycomb)の紹介動画登場。UIの刷新、WEBブラウザに上部タブ登場、Gmailの2画面表示、ビデオチャット対応など


この動画に登場する端末、よく見るとMotorola XOOMですね。





CES2011でAndroid3.0が話題らしいですが・・・



某所からCES2011でAndroid3.0が爆発しているという話があったので、
関連すると思われるCES2011の動画を一通り見てみました。
結論から言うと、「最終的には3.0をのせるよ」というメーカーがほとんどで、
Android 3.0がどういったものかといった情報は今のところ特に得られませんでした。
CES2011と関連しているかは不明ですがGoogleが公式でアップしたとおぼしき動画があり、
そちらではかなり詳しくAndroid3.0に触れています(最下部にあります)。


Android3.0にするよ、と言っているメーカーの動画を紹介します。


Sony Ericsson Arc



D


Xperia arcの外観くるくる。
下記公式のブログでは2.3が乗ってるけどアップデートで3.0にする、と言っている模様
http://www.blogsonyericsson.com/2011/01/05/ces-2011-conoce-al-nuevo-sony-ericsson-xperia-arc/





Toshiba Honey Comb Tablet



D


東芝のタブレット端末の説明
動画ではAndroid2.2で動作している。
最終的には3.0をのせると言っている模様。





ASUS eeePad



D


10.1インチ版はAndroid3.0らしいが、
デモの人が持って写真とらせてるだけ。
12インチ版はWindows7。
モニタ部分を外したり付けたり





[Android 3.0]


Google公式の?Android OS3.0 Honey Comb紹介動画



D


元はGoogle公式の動画らしいですが、公開後すぐに削除されたようです。
有志らが閲覧した際に保存していた動画を再アップしている模様です。
CES2011と関連があるかは不明
ここではAndroid3.0について詳しく紹介がされています。
内容の説明についてはコチラを参照してください。
革新的なOSへ。Android 3.0(Honeycomb)の紹介動画登場。UIの刷新、WEBブラウザに上部タブ登場、Gmailの2画面表示、ビデオチャット対応など


この動画に登場する端末、よく見るとMotorola XOOMですね。







f:id:bs-android:20110105214115p:image


A5協会(Ahoな Android Application Award Association)が主催しているA4(Ahoな Android Application Award)ですが、実は昨年末からヒッソリと投票受付を開始しています。



A4とは


Ahoなアプリをみんなで勝手に選んで表彰するイベントです。


A3(Android Application Award) 2010 Springの前日の2010/6/23に第一回の表彰が行われています。


日経BPさん公認黙認のイベントとなっています。


A4公式サイト



前回から機能が追加されており、投票者が好きにタグ付けできるようになっています。(ニコニコ動画のようなイメージ)


起動画面。


f:id:bs-android:20110105220641p:image:w240


"とうひょうする"のボタンを押すと端末にインストールされているアプリのリストが出ます。


※初回起動時はTwitterアカウントを設定するかどうか聞いてきます。


f:id:bs-android:20110105220739p:image:w240


リストのアプリをタップしたところ。


f:id:bs-android:20110105220433p:image:w240


"新規タグ"のボタンを押すと、オリジナルのタグを作成できます。


f:id:bs-android:20110105220445p:image:w240


ジャンルとタグを選択して、投票ボタンで投票してください。


トップ画面で"らんきんぐみる"のボタンを押すと、現在の投票ランキングを見ることができます。


f:id:bs-android:20110105221503p:image:w240


リストからアプリを選択すると詳細が見れます。


f:id:bs-android:20110105221550p:image:w240


Android Marketに公開されているアプリであれば、"AndroidMarketを表示する"のボタンで、Android Marketの詳細画面に飛びます。


f:id:bs-android:20110105221819p:image:w240





みなさんも、どしどし投票したり、面白いアプリを作って投票したりしてくださいまし!





A4投票アプリのダウンロード


投票アプリはAndroid Marketで"A4"と検索するか、以下のQRコードをAndroid端末で読み取ってください。


http://ahoapp.appspot.com/images/a4qr.png





Android端末でこのページを見ている場合は以下のリンクからでもAndroid Marketを起動できます。


Android Marketへのリンク



Special Thanks!


以下の開発者の方々の協力でA4は成り立っています。ありがとうございます!



Androidもくもく勉強会 Expert Developers



Name: Akihiro Kobayashi


twitter: @hidecheck


hp: http://d.hatena.ne.jp/hidecheck/


mail: hidecheck[at]gmail.com




Name: Kosei Kitahara


twitter: @Surgo


hp: http://surgo.jp/


mail: surgo.jp[at]gmail.com




Name: a_yama (tab02733)


twitter: @tab02733


hp: http://homepage2.nifty.com/a-yama/


mail: tab02733[at]gmail.com




Name: げんすけ


twitter: @gen_suke








A4 2011 Winter の投票、はじまってます。



f:id:bs-android:20110105214115p:image


A5協会(Ahoな Android Application Award Association)が主催しているA4(Ahoな Android Application Award)ですが、実は昨年末からヒッソリと投票受付を開始しています。



A4とは


Ahoなアプリをみんなで勝手に選んで表彰するイベントです。


A3(Android Application Award) 2010 Springの前日の2010/6/23に第一回の表彰が行われています。


日経BPさん公認黙認のイベントとなっています。


A4公式サイト



前回から機能が追加されており、投票者が好きにタグ付けできるようになっています。(ニコニコ動画のようなイメージ)


起動画面。


f:id:bs-android:20110105220641p:image:w240


"とうひょうする"のボタンを押すと端末にインストールされているアプリのリストが出ます。


※初回起動時はTwitterアカウントを設定するかどうか聞いてきます。


f:id:bs-android:20110105220739p:image:w240


リストのアプリをタップしたところ。


f:id:bs-android:20110105220433p:image:w240


"新規タグ"のボタンを押すと、オリジナルのタグを作成できます。


f:id:bs-android:20110105220445p:image:w240


ジャンルとタグを選択して、投票ボタンで投票してください。


トップ画面で"らんきんぐみる"のボタンを押すと、現在の投票ランキングを見ることができます。


f:id:bs-android:20110105221503p:image:w240


リストからアプリを選択すると詳細が見れます。


f:id:bs-android:20110105221550p:image:w240


Android Marketに公開されているアプリであれば、"AndroidMarketを表示する"のボタンで、Android Marketの詳細画面に飛びます。


f:id:bs-android:20110105221819p:image:w240





みなさんも、どしどし投票したり、面白いアプリを作って投票したりしてくださいまし!





A4投票アプリのダウンロード


投票アプリはAndroid Marketで"A4"と検索するか、以下のQRコードをAndroid端末で読み取ってください。


http://ahoapp.appspot.com/images/a4qr.png





Android端末でこのページを見ている場合は以下のリンクからでもAndroid Marketを起動できます。


Android Marketへのリンク



Special Thanks!


以下の開発者の方々の協力でA4は成り立っています。ありがとうございます!



Androidもくもく勉強会 Expert Developers



Name: Akihiro Kobayashi


twitter: @hidecheck


hp: http://d.hatena.ne.jp/hidecheck/


mail: hidecheck[at]gmail.com




Name: Kosei Kitahara


twitter: @Surgo


hp: http://surgo.jp/


mail: surgo.jp[at]gmail.com




Name: a_yama (tab02733)


twitter: @tab02733


hp: http://homepage2.nifty.com/a-yama/


mail: tab02733[at]gmail.com




Name: げんすけ


twitter: @gen_suke








Related Posts Plugin for WordPress, Blogger...