我想创建一个使用AudioStream/AudioGroup工作的VoIP系统,并且只能使用本地WiFi热点。我在android设备1上创建了一个WiFi热点,并将设备2连接到它。当我填写设备1的本地IP地址(通过getLocalIPAddress((获得(和设备2的IP地址(在设备1上通过fetchIPs((方法获得(,并在两个设备上单击"连接"时,代码不会引发任何异常,但我听不到任何设备的麦克风音频。
注1:此代码取自@murphybro2的此答案,并略有更改。注2:在设备1(主机(上使用getLocalIPAddress((时,ip地址返回为115.163.242.10,而从设备2获取的ip的格式为192.168.xxx.yyy
我将android.permission.INTERNET、android.pPermission.ACCESS_WIFI_STATE和android.ppermission.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>
dimens.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="activity_vertical_margin">8dp</dimen>
<dimen name="activity_horizontal_margin">8dp</dimen>
</resources>
getLocalIPAddress((应该返回Wifi网络接口的IP地址。
在当前代码中,您将返回列表中网络接口的第一个IP地址。
您应该检查netInterface.getName((,并与wifi接口名称进行比较,然后返回IP地址。
一旦您的IP地址正确,您就可以继续操作。