Added SIP Demo to sample apps.
Change-Id: Id98b6e542e1be5b9822a696936e735406c08500f
This commit is contained in:
@@ -160,6 +160,7 @@ development/samples/MultiResolution samples/${PLATFORM_NAME}/MultiResol
|
|||||||
development/samples/NotePad samples/${PLATFORM_NAME}/NotePad
|
development/samples/NotePad samples/${PLATFORM_NAME}/NotePad
|
||||||
development/samples/SampleSyncAdapter samples/${PLATFORM_NAME}/SampleSyncAdapter
|
development/samples/SampleSyncAdapter samples/${PLATFORM_NAME}/SampleSyncAdapter
|
||||||
development/samples/SearchableDictionary samples/${PLATFORM_NAME}/SearchableDictionary
|
development/samples/SearchableDictionary samples/${PLATFORM_NAME}/SearchableDictionary
|
||||||
|
development/samples/SipDemo samples/${PLATFORM_NAME}/SipDemo
|
||||||
development/samples/SkeletonApp samples/${PLATFORM_NAME}/SkeletonApp
|
development/samples/SkeletonApp samples/${PLATFORM_NAME}/SkeletonApp
|
||||||
development/samples/Snake samples/${PLATFORM_NAME}/Snake
|
development/samples/Snake samples/${PLATFORM_NAME}/Snake
|
||||||
development/samples/SoftKeyboard samples/${PLATFORM_NAME}/SoftKeyboard
|
development/samples/SoftKeyboard samples/${PLATFORM_NAME}/SoftKeyboard
|
||||||
|
|||||||
16
samples/SipDemo/Android.mk
Normal file
16
samples/SipDemo/Android.mk
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := samples
|
||||||
|
|
||||||
|
# Only compile source java files in this apk.
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||||
|
|
||||||
|
LOCAL_PACKAGE_NAME := SipDemo
|
||||||
|
|
||||||
|
LOCAL_SDK_VERSION := current
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
|
|
||||||
|
# Use the following include to make our test apk.
|
||||||
|
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||||
44
samples/SipDemo/AndroidManifest.xml
Normal file
44
samples/SipDemo/AndroidManifest.xml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2010 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.example.android.sip">
|
||||||
|
<application android:icon="@drawable/icon" android:label="SipDemo">
|
||||||
|
<activity android:name=".WalkieTalkieActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".SipSettings" android:label="set_preferences"/>
|
||||||
|
|
||||||
|
|
||||||
|
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
|
||||||
|
</application>
|
||||||
|
<uses-sdk android:minSdkVersion="9" />
|
||||||
|
<uses-permission android:name="android.permission.USE_SIP" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
|
||||||
|
<uses-feature android:name="android.hardware.sip.voip" android:required="true" />
|
||||||
|
<uses-feature android:name="android.hardware.wifi" android:required="true" />
|
||||||
|
<uses-feature android:name="android.hardware.microphone" android:required="true" />
|
||||||
|
</manifest>
|
||||||
52
samples/SipDemo/_index.html
Normal file
52
samples/SipDemo/_index.html
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<p>This is a demo application highlighting how to make internet-based calls with
|
||||||
|
the SIP API. The application uses a walkie-talkie style interface, allowing you
|
||||||
|
to only be heard when the button is pushed down.</p>
|
||||||
|
|
||||||
|
<p>The source code for this demo app shows how to accomplish three key things
|
||||||
|
with SIP: Make a call, receive a call, and signal to the Android platform that
|
||||||
|
your app wants to receive incoming SIP calls, so that they can be handled from
|
||||||
|
within the application.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>The application includes:<p>
|
||||||
|
<ul> <li><a
|
||||||
|
href="src/com/example/android/sip/SipSettings.html"><code>SipSettings</code></a>
|
||||||
|
— a <code>PreferenceActivity</code> that supplies basic settings for SIP
|
||||||
|
authentication.</li> <li><a
|
||||||
|
href="src/com/example/android/sip/cube1/IncomingCallReceiver.html"><code>
|
||||||
|
IncomingCallReceiver</code></a> — a <code>BroadcastReceiver</code>
|
||||||
|
that listens for incoming SIP calls and passes them to
|
||||||
|
<code>WalkieTalkieActivity</code> for handling.</li> <li><a
|
||||||
|
href="src/com/example/android/sip/WalkieTalkieActivity.html"><code>WalkieTalkieActivity</code></a>
|
||||||
|
— a activity that login to SIP provider and registers the device to
|
||||||
|
receive incoming SIP, handles incoming calls and makes outgoing calls, managing
|
||||||
|
UI during the call.</li> </ul>
|
||||||
|
<p>If you are developing an application that uses the SIP API, remember that the
|
||||||
|
feature is supported only on Android 2.3 (API level 9) and higher versions of
|
||||||
|
the platform. Also, among devices running Android 2.3 (API level 9) or higher,
|
||||||
|
not all devices will offer SIP support. To ensure that your application can only
|
||||||
|
be installed on devices that are capable of supporting SIP, remember to add the
|
||||||
|
following to the application's manifest before publishing to Android Market:</p>
|
||||||
|
<ul> <li><code><uses-sdk android:minSdkVersion="9" /></code>, which
|
||||||
|
indicates to Android Market and the platform that your application requires
|
||||||
|
Android 2.3 or higher. For more information, see <a
|
||||||
|
href="../../../guide/appendix/api-levels.html">API Levels</a> and the
|
||||||
|
documentation for the <a
|
||||||
|
href="../../../guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
|
||||||
|
element.</li> </ul> <p>To control how Android Market filters your application
|
||||||
|
from devices that do not support SIP, remember to add the following to the
|
||||||
|
application's manifest <ul> <li><code><uses-feature
|
||||||
|
android:name="android.hardware.sip.voip" /></code>, which tells Android
|
||||||
|
Market that your application uses the SIP API. The declaration should include
|
||||||
|
an <code>android:required</code> attribute that indicates whether you want
|
||||||
|
Android Market to filter the application from devices that do not offer SIP
|
||||||
|
support. Other <code><uses-feature></code> declarations may also be
|
||||||
|
needed, depending on your implementation. For more information, see the
|
||||||
|
documentation for the <a
|
||||||
|
href="../../../guide/topics/manifest/uses-feature-element.html"><code><uses-feature></code></a>
|
||||||
|
element.</li> </ul>
|
||||||
|
<p>For more information about using the SIP API, see the <a
|
||||||
|
href="../../../reference/android/net/sip/package-summary.html"><code>android.net.sip</a></code>
|
||||||
|
documentation. </p>
|
||||||
|
|
||||||
|
<img alt="" src="../images/SipDemo.png" />
|
||||||
23
samples/SipDemo/res/drawable/btn_record.xml
Normal file
23
samples/SipDemo/res/drawable/btn_record.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2010 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true" android:drawable="@drawable/btn_speak_pressed" />
|
||||||
|
<item android:state_selected="true" android:drawable="@drawable/btn_speak_pressed" />
|
||||||
|
<item android:drawable="@drawable/btn_speak_normal" />
|
||||||
|
</selector>
|
||||||
|
|
||||||
BIN
samples/SipDemo/res/drawable/btn_speak_normal.png
Normal file
BIN
samples/SipDemo/res/drawable/btn_speak_normal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
samples/SipDemo/res/drawable/btn_speak_pressed.png
Normal file
BIN
samples/SipDemo/res/drawable/btn_speak_pressed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
BIN
samples/SipDemo/res/drawable/btn_speak_selected.png
Normal file
BIN
samples/SipDemo/res/drawable/btn_speak_selected.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
samples/SipDemo/res/drawable/icon.png
Normal file
BIN
samples/SipDemo/res/drawable/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
45
samples/SipDemo/res/layout/call_address_dialog.xml
Normal file
45
samples/SipDemo/res/layout/call_address_dialog.xml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2010 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/calladdress_view"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_marginLeft="20dip"
|
||||||
|
android:layout_marginRight="20dip"
|
||||||
|
android:text="@+string/contactAddress"
|
||||||
|
android:gravity="left"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/calladdress_edit"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_marginLeft="20dip"
|
||||||
|
android:layout_marginRight="20dip"
|
||||||
|
android:scrollHorizontally="true"
|
||||||
|
android:autoText="false"
|
||||||
|
android:capitalize="none"
|
||||||
|
android:gravity="fill_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
49
samples/SipDemo/res/layout/walkietalkie.xml
Normal file
49
samples/SipDemo/res/layout/walkietalkie.xml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2010 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
<RelativeLayout android:padding="12dp"
|
||||||
|
android:id="@+id/mainlayout"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/sipLabel"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ToggleButton
|
||||||
|
android:layout_height="400dp"
|
||||||
|
android:layout_width="400dp"
|
||||||
|
android:text="@+string/talk"
|
||||||
|
android:id="@+id/pushToTalk"
|
||||||
|
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:background="@drawable/btn_record"
|
||||||
|
android:textOff=""
|
||||||
|
android:textOn=""
|
||||||
|
android:layout_marginTop="-20dp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</FrameLayout>
|
||||||
22
samples/SipDemo/res/values/strings.xml
Normal file
22
samples/SipDemo/res/values/strings.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2010 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">SIP Demo</string>
|
||||||
|
<string name="contactAddress">SIP Address to contact</string>
|
||||||
|
<string name="talk">Talk</string>
|
||||||
|
</resources>
|
||||||
38
samples/SipDemo/res/xml/preferences.xml
Normal file
38
samples/SipDemo/res/xml/preferences.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2010 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<EditTextPreference
|
||||||
|
android:name="SIP Username"
|
||||||
|
android:summary="Username for your SIP Account"
|
||||||
|
android:defaultValue=""
|
||||||
|
android:title="Enter Username"
|
||||||
|
android:key="namePref" />
|
||||||
|
<EditTextPreference
|
||||||
|
android:name="SIP Domain"
|
||||||
|
android:summary="Domain for your SIP Account"
|
||||||
|
android:defaultValue=""
|
||||||
|
android:title="Enter Domain"
|
||||||
|
android:key="domainPref" />
|
||||||
|
<EditTextPreference
|
||||||
|
android:name="SIP Password"
|
||||||
|
android:summary="Password for your SIP Account"
|
||||||
|
android:defaultValue=""
|
||||||
|
android:title="Enter Password"
|
||||||
|
android:key="passPref"
|
||||||
|
android:password="true" />
|
||||||
|
</PreferenceScreen>
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.android.sip;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.sip.*;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity.
|
||||||
|
*/
|
||||||
|
public class IncomingCallReceiver extends BroadcastReceiver {
|
||||||
|
/**
|
||||||
|
* Processes the incoming call, answers it, and hands it over to the
|
||||||
|
* WalkieTalkieActivity.
|
||||||
|
* @param context The context under which the receiver is running.
|
||||||
|
* @param intent The intent being received.
|
||||||
|
*/
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
samples/SipDemo/src/com/example/android/sip/SipSettings.java
Normal file
34
samples/SipDemo/src/com/example/android/sip/SipSettings.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.android.sip;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles SIP authentication settings for the Walkie Talkie app.
|
||||||
|
*/
|
||||||
|
public class SipSettings extends PreferenceActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
// Note that none of the preferences are actually defined here.
|
||||||
|
// They're all in the XML file res/xml/preferences.xml.
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
addPreferencesFromResource(R.xml.preferences);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,358 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.android.sip;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.*;
|
||||||
|
import android.net.sip.*;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles all calling, receiving calls, and UI interaction in the WalkieTalkie app.
|
||||||
|
*/
|
||||||
|
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
|
||||||
|
|
||||||
|
public String sipAddress = null;
|
||||||
|
|
||||||
|
public SipManager manager = null;
|
||||||
|
public SipProfile me = null;
|
||||||
|
public SipAudioCall call = null;
|
||||||
|
public IncomingCallReceiver callReceiver;
|
||||||
|
|
||||||
|
private static final int CALL_ADDRESS = 1;
|
||||||
|
private static final int SET_AUTH_INFO = 2;
|
||||||
|
private static final int UPDATE_SETTINGS_DIALOG = 3;
|
||||||
|
private static final int HANG_UP = 4;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.walkietalkie);
|
||||||
|
|
||||||
|
ToggleButton pushToTalkButton = (ToggleButton) findViewById(R.id.pushToTalk);
|
||||||
|
pushToTalkButton.setOnTouchListener(this);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// "Push to talk" can be a serious pain when the screen keeps turning off.
|
||||||
|
// Let's prevent that.
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
|
||||||
|
initializeManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
// When we get back from the preference setting Activity, assume
|
||||||
|
// settings have changed, and re-login with new auth info.
|
||||||
|
initializeManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (call != null) {
|
||||||
|
call.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
closeLocalProfile();
|
||||||
|
|
||||||
|
if (callReceiver != null) {
|
||||||
|
this.unregisterReceiver(callReceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initializeManager() {
|
||||||
|
if(manager == null) {
|
||||||
|
manager = SipManager.newInstance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeLocalProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs you into your SIP provider, registering this device as the location to
|
||||||
|
* send SIP calls to for your SIP address.
|
||||||
|
*/
|
||||||
|
public void initializeLocalProfile() {
|
||||||
|
if (manager == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me != null) {
|
||||||
|
closeLocalProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
||||||
|
String username = prefs.getString("namePref", "");
|
||||||
|
String domain = prefs.getString("domainPref", "");
|
||||||
|
String password = prefs.getString("passPref", "");
|
||||||
|
|
||||||
|
if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
|
||||||
|
showDialog(UPDATE_SETTINGS_DIALOG);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
|
||||||
|
builder.setPassword(password);
|
||||||
|
me = builder.build();
|
||||||
|
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (ParseException pe) {
|
||||||
|
updateStatus("Connection Error.");
|
||||||
|
} catch (SipException se) {
|
||||||
|
updateStatus("Connection error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes out your local profile, freeing associated objects into memory
|
||||||
|
* and unregistering your device from the server.
|
||||||
|
*/
|
||||||
|
public void closeLocalProfile() {
|
||||||
|
if (manager == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (me != null) {
|
||||||
|
manager.close(me.getUriString());
|
||||||
|
}
|
||||||
|
} catch (Exception ee) {
|
||||||
|
Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make an outgoing call.
|
||||||
|
*/
|
||||||
|
public void initiateCall() {
|
||||||
|
|
||||||
|
updateStatus(sipAddress);
|
||||||
|
|
||||||
|
try {
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
|
||||||
|
if (me != null) {
|
||||||
|
try {
|
||||||
|
manager.close(me.getUriString());
|
||||||
|
} catch (Exception ee) {
|
||||||
|
Log.i("WalkieTalkieActivity/InitiateCall",
|
||||||
|
"Error when trying to close manager.", ee);
|
||||||
|
ee.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (call != null) {
|
||||||
|
call.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the status box at the top of the UI with a messege of your choice.
|
||||||
|
* @param status The String to display in the status box.
|
||||||
|
*/
|
||||||
|
public void updateStatus(final String status) {
|
||||||
|
// Be a good citizen. Make sure UI changes fire on the UI thread.
|
||||||
|
this.runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
TextView labelView = (TextView) findViewById(R.id.sipLabel);
|
||||||
|
labelView.setText(status);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the status box with the SIP address of the current call.
|
||||||
|
* @param call The current, active call.
|
||||||
|
*/
|
||||||
|
public void updateStatus(SipAudioCall call) {
|
||||||
|
String useName = call.getPeerProfile().getDisplayName();
|
||||||
|
if(useName == null) {
|
||||||
|
useName = call.getPeerProfile().getUserName();
|
||||||
|
}
|
||||||
|
updateStatus(useName + "@" + call.getPeerProfile().getSipDomain());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates whether or not the user's voice is muted, depending on whether the button is pressed.
|
||||||
|
* @param v The View where the touch event is being fired.
|
||||||
|
* @param event The motion to act on.
|
||||||
|
* @return boolean Returns false to indicate that the parent view should handle the touch event
|
||||||
|
* as it normally would.
|
||||||
|
*/
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
if (call == null) {
|
||||||
|
return false;
|
||||||
|
} else if (event.getAction() == MotionEvent.ACTION_DOWN && call != null && call.isMuted()) {
|
||||||
|
call.toggleMute();
|
||||||
|
} else if (event.getAction() == MotionEvent.ACTION_UP && !call.isMuted()) {
|
||||||
|
call.toggleMute();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
menu.add(0, CALL_ADDRESS, 0, "Call someone");
|
||||||
|
menu.add(0, SET_AUTH_INFO, 0, "Edit your SIP Info.");
|
||||||
|
menu.add(0, HANG_UP, 0, "End Current Call.");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case CALL_ADDRESS:
|
||||||
|
showDialog(CALL_ADDRESS);
|
||||||
|
break;
|
||||||
|
case SET_AUTH_INFO:
|
||||||
|
updatePreferences();
|
||||||
|
break;
|
||||||
|
case HANG_UP:
|
||||||
|
if(call != null) {
|
||||||
|
try {
|
||||||
|
call.endCall();
|
||||||
|
} catch (SipException se) {
|
||||||
|
Log.d("WalkieTalkieActivity/onOptionsItemSelected",
|
||||||
|
"Error ending call.", se);
|
||||||
|
}
|
||||||
|
call.close();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Dialog onCreateDialog(int id) {
|
||||||
|
switch (id) {
|
||||||
|
case CALL_ADDRESS:
|
||||||
|
|
||||||
|
LayoutInflater factory = LayoutInflater.from(this);
|
||||||
|
final View textBoxView = factory.inflate(R.layout.call_address_dialog, null);
|
||||||
|
return new AlertDialog.Builder(this)
|
||||||
|
.setTitle("Call Someone.")
|
||||||
|
.setView(textBoxView)
|
||||||
|
.setPositiveButton(
|
||||||
|
android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
EditText textField = (EditText)
|
||||||
|
(textBoxView.findViewById(R.id.calladdress_edit));
|
||||||
|
sipAddress = textField.getText().toString();
|
||||||
|
initiateCall();
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(
|
||||||
|
android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
// Noop.
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
|
||||||
|
case UPDATE_SETTINGS_DIALOG:
|
||||||
|
return new AlertDialog.Builder(this)
|
||||||
|
.setMessage("Please update your SIP Account Settings.")
|
||||||
|
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
updatePreferences();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(
|
||||||
|
android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
// Noop.
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePreferences() {
|
||||||
|
Intent settingsActivity = new Intent(getBaseContext(),
|
||||||
|
SipSettings.class);
|
||||||
|
startActivity(settingsActivity);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user