2つのAndroidデバイス間でVOIPアプリケーションを開発する必要があります。
私が知っているように、この目的で使用されるSIPプロトコルがありますが、SIPサーバーへの登録とSIPシグナリングのためのインターネットへのアクセスが必要です。
インターネットにアクセスせずにAndroidでVOIPアプリケーションを作成する方法はありますか?
5 に答える
もちろん可能です!なぜインターネットが必要なのですか?両方が同じネットワークに接続されていれば問題ありません。以下は、動作中のアプリの Java と xml です。
起動時に、「52022」などの独自のローカルポートが提供されます。これは毎回ランダムであり、残念ながら仕方がありません。次に、他の電話の IP アドレスとランダムに生成されたポート番号を入力し、接続を押します。それらはまったく同じことを行い、万歳、接続されました! このテスト アプリでは、ポート番号を交換するために近くにいる必要があることは明らかですが、適切なアプリでは、接続する前に各ポート番号を簡単に要求できました。お役に立てれば!
public class MainActivity extends Activity {
AudioGroup m_AudioGroup;
AudioStream m_AudioStream;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
m_AudioGroup = new AudioGroup();
m_AudioGroup.setMode(AudioGroup.MODE_NORMAL);
m_AudioStream = new AudioStream(InetAddress.getByAddress(getLocalIPAddress ()));
int localPort = m_AudioStream.getLocalPort();
m_AudioStream.setCodec(AudioCodec.PCMU);
m_AudioStream.setMode(RtpStream.MODE_NORMAL);
((TextView)findViewById(R.id.lblLocalPort)).setText(String.valueOf(localPort));
((Button) findViewById(R.id.button1)).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String remoteAddress = ((EditText)findViewById(R.id.editText2)).getText().toString();
String remotePort = ((EditText)findViewById(R.id.editText1)).getText().toString();
try {
m_AudioStream.associate(InetAddress.getByName(remoteAddress), Integer.parseInt(remotePort));
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
m_AudioStream.join(m_AudioGroup);
}
});
((Button) findViewById(R.id.button2)).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
m_AudioStream.release();
}
});
} catch (Exception e) {
Log.e("----------------------", e.toString());
e.printStackTrace();
}
}
public static byte[] getLocalIPAddress () {
byte ip[]=null;
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
ip= inetAddress.getAddress();
}
}
}
} catch (SocketException ex) {
Log.i("SocketException ", ex.toString());
}
return ip;
}
}
レイアウト ファイル:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/lblLocalPort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/localPort" />
<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="@string/iPHint"
android:inputType="phone" />
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="@string/portHint"
android:inputType="number" >
<requestFocus />
</EditText>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/connect" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Disconnect" />
</LinearLayout>
</LinearLayout>
編集: IP アドレス メソッドは API 22 で機能しなくなりました。以下のコードを使用してください。
private byte[] getLocalIPAddress() {
byte[] bytes = null;
try {
// get the string ip
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
// convert to bytes
InetAddress inetAddress = null;
try {
inetAddress = InetAddress.getByName(ip);
} catch (UnknownHostException e) {
e.printStackTrace();
}
bytes = new byte[0];
if (inetAddress != null) {
bytes = inetAddress.getAddress();
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, R.string.phone_voip_incompatible, Toast.LENGTH_SHORT).show();
}
return bytes;
}
実際、SIP クライアントはピアツーピアで通信できます。IP アドレスと、SIP メッセージをリッスンする UDP ポートを知る必要があるだけです。
2 台のコンピューター (Windows 用の X-Lite、Linux 用の Twinkle なども存在します) で通常の SIP クライアントをいじって、サーバー登録なしでそれらの間で通話を確立してみてください。それはかなり可能です。
また、ローカル LAN のどこかで最小限の SIP サーバーを実行することもできます。たとえば、FreeSWITCH は非常に小さいフットプリントに最小化できます。
Androidを含む複数のプラットフォームで p2p voip サービスにJITSIを使用できると思います。
これらは、このプロジェクトに関する私の調査結果です:-
- サーバーやインターネット接続は必要ありません。
- ユーザーは同じネットワークに属している必要があります。
- オープンソース。
- Android apk が利用可能です。ほとんどの場合、Web サイトでコードを見つけるか、逆コンパイルすることができます。
わかりましたので、ピアツーピア通信を探しているなら、wifi が最適だと思います (より良い距離と速度)。Android の新しいバージョンのみを開発できる場合は、WI-FI Directが適していますが、これは Android 4.0 以降でのみ機能します。
4.0 未満で何かを実行するには、サードパーティのライブラリを使用する必要があります。Qualcomm にalljoynというライブラリがあることは知っていますが、それがどれほど優れているかはわかりません。
VOIPコールはインターネットとsipサーバーを経由するため、できません。
例えば 。VOIP ダイラー経由で国外に電話をかけたい場合は、Bluetooth 経由で通信できないため、インターネット アクセスが必要です。
ありがとう。