Я хочу создать систему VoIP, которая работает с AudioStream / AudioGroup и может работать только с локальной точкой доступа WiFi. Я создаю WiFi-Hotspot на устройстве Android 1 и подключаю устройство 2 к нему. Когда я заполняю локальный IP-адрес устройства device1, который я получаю с помощью getLocalIPAddress (), и IP-адрес устройства device2, который я получаю с помощью метода fetchIPs () на device1, и нажимаю «Подключить» на обоих устройствах, кодне выдает никаких исключений, но я не слышу звук микрофона ни одного из устройств.
Примечание 1: Этот код взят из этого ответа @ murphybro2 и немного изменен. Примечание 2: При использовании getLocalIPAddress () на device1 (хост) IP-адрес возвращается как 115.163.242.10, в то время как извлеченный IP-адрес с device2 имеет форму 192.168.xxx.yyy
Я ставлю android.permission. ИНТЕРНЕТ, android.permission.ACCESS_WIFI_STATE и android.permission.RECORD_AUDIO в файл манифеста
MainActivity.java:
package com.applications.fihdi.testapp487623;
import android.content.Context;
import android.media.AudioManager;
import android.net.rtp.*;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.widget.*;
import java.io.*;
import java.net.*;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@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 {
String ip = getLocalIPAddress();
Log.d("VOIP","String ip: " + ip);
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
final AudioGroup m_AudioGroup = new AudioGroup();
m_AudioGroup.setMode(AudioGroup.MODE_NORMAL);
final AudioStream m_AudioStream = new AudioStream(InetAddress.getByName(ip));
Log.d("VOIP","localhost (same as ip??): = " + InetAddress.getLocalHost());
int localPort = m_AudioStream.getLocalPort();
Log.d("VOIP","Local Port: "+ Integer.toString(localPort));
m_AudioStream.setCodec(AudioCodec.PCMU);
m_AudioStream.setMode(RtpStream.MODE_NORMAL);
((TextView) findViewById(R.id.lblLocalPort)).setText(String.valueOf(localPort));
((TextView) findViewById(R.id.statusLabel)).setText("Status: local port number generated");
findViewById(R.id.connectButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("VOIP","ConnectButton pressed");
String remoteAddress;
String remotePort;
remoteAddress = ((EditText) findViewById(R.id.editText2)).getText().toString();
//String remoteAddress = fetchIPs().get(0);
remotePort = ((EditText) findViewById(R.id.editText1)).getText().toString();
//Log.d("VOIP", fetchIPs().get(0));
try {
m_AudioStream.associate(InetAddress.getByName(remoteAddress), Integer.parseInt(remotePort));
Log.d("VOIP","AudioStream associated");
((TextView) findViewById(R.id.statusLabel)).setText("Status: connected to: " + fetchIPs().get(0));
m_AudioStream.join(m_AudioGroup);
Log.d("VOIP","AudioStream joined");
} catch (Exception e) {
((TextView) findViewById(R.id.statusLabel)).setText("Couldn't connect");
Log.d("VOIP","Exception with associating");
}
}
});
findViewById(R.id.DisconnectButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
m_AudioStream.release();
}
});
} catch (Exception e) {
Log.e("VOIP", "Exception when setting up the Audiostream!");
e.printStackTrace();
}
findViewById(R.id.fetchButtons).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("VOIP","FetchIp Button pressed");
ArrayList<String> connectedIPs = fetchIPs();
((EditText) findViewById(R.id.editText2)).setText(connectedIPs.get(0));
for(int i = 0; i<connectedIPs.size(); i++){
Log.d("VOIP", "connectedIps[" + i + "]: " + connectedIPs.get(i));
}
}
});
}
public String getLocalIPAddress() {
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()) {
String ip = Formatter.formatIpAddress(inetAddress.hashCode());
Log.d("VOIP", "***** IP="+ ip);
return ip;
}
}
}
} catch (SocketException ex) {
Log.e("VOIP", ex.toString());
}
return null;
}
public ArrayList<String> fetchIPs() {
BufferedReader bufRead = null;
ArrayList<String> result = null;
try {
result = new ArrayList<String>();
bufRead = new BufferedReader(new FileReader("/proc/net/arp"));
String fileLine;
while ((fileLine = bufRead.readLine()) != null) {
String[] splitted = fileLine.split(" +");
if ((splitted != null) && (splitted.length >= 4)) {
String mac = splitted[3];
if (mac.matches("..:..:..:..:..:..")) {
try {
String ping = "ping -c 1 -W 1 " + splitted[0];
Runtime run = Runtime.getRuntime();
Process pro = run.exec(ping);
try {
pro.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
int exit = pro.exitValue();
if (exit == 0) {
result.add(splitted[0]);
} else {
throw new Exception();
}
} catch (Exception e) {
Log.d("MainActivity", "Something went wrong with pinging the adress: " + splitted[0]);
Log.d("MainActivity", e.getMessage());
}
}
}
}
} catch (Exception e) {
}
try {
bufRead.close();
} catch (Exception e) {
}
return result;
}
}
main_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<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/connectButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/connect" />
<Button
android:id="@+id/DisconnectButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Disconnect" />
<Button
android:id="@+id/fetchButtons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Fetch IPs" />
</LinearLayout>
<TextView
android:id="@+id/statusLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
измерения.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="activity_vertical_margin">8dp</dimen>
<dimen name="activity_horizontal_margin">8dp</dimen>
</resources>