【问题标题】:Android VOIP application without access to internetAndroid VOIP 应用程序无法访问互联网
【发布时间】:2012-06-24 11:17:04
【问题描述】:

我需要在 2 个安卓设备之间开发 VOIP 应用程序。
据我所知,有一个用于此目的的 SIP 协议,但它需要注册到 SIP 服务器并访问互联网以进行 SIP 信令。
有什么方法可以在没有互联网访问的情况下在 android 中创建 VOIP 应用程序?

【问题讨论】:

  • 你的意思是像一种对讲机吗?有很多方法可以通过 wifi 和蓝牙进行点对点,这能满足您的需求吗?
  • 是的。实际上我需要一对多的对讲机,有wifi。无法访问互联网的会议类型
  • SIP 不需要互联网访问,也不需要用户代理本身以外的任何东西。 (这些东西有用,但不是必需。)
  • @FrankShearar 请描述一下这怎么可能?看我的问题:stackoverflow.com/questions/25520246/local-voip-call-with-sip
  • @CostaMirkin 现在怎么样了?

标签: android sip voip


【解决方案1】:

当然可以!为什么你需要互联网?只要你们都连接到同一个网络就可以了!下面是一个工作应用程序的 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;
}

【讨论】:

  • 我得到这个异常 E/------------------------: java.net.SocketException: Invalid argument
  • 自从我使用它已经有一段时间了,我知道获取 IP 地址的方式在最近的 android 更新中发生了变化。
  • 你能指导我如何通过本地 wifi 从一台安卓设备到另一台设备进行语音通话吗?
  • 查看修改后的代码,换掉新的ip地址方式
  • 它现在正在工作,但在按下连接后什么都没有发生。我应该怎么做才能在按下连接后连接到另一台设备并且应该能够传输语音。
【解决方案2】:

实际上 SIP 客户端可以进行点对点通信,他们只需要知道自己的 IP 地址和侦听 SIP 消息的 UDP 端口即可。

您可以在两个通勤者上使用普通的 SIP 客户端(Windows 的 X-Lite、Linux 的 Twinkle 等也存在),并尝试在它们之间建立呼叫而无需服务器注册。很有可能。

您还可以在本地 LAN 的某处运行简约的 SIP 服务器。例如,FreeSWITCH 可以最小化到一个非常小的占用空间。

【讨论】:

  • FreeSWITCH可以安装在Android上吗?
  • 不,我不这么认为。它是用 C 编写的,android 是基于 java 的
  • Android 是基于 LINUX C,Java 是在 C 之上添加的
  • 可以,但是你不能在无根手机上安装native-C应用程序
  • 对于点对多点通信,我绝对推荐在同一 LAN 中的服务器上安装 FreeSWITCH。如果您的 Wifi 接入点足够强大,您也可以尝试在那里安装它。好吧,无论如何,学习这个平台还需要一周的时间......
【解决方案3】:

好的,所以如果您正在寻找一些对等通信,我认为 wifi 是要走的路(更好的距离和速度)。如果您只能为较新版本的 Android 进行开发,那么 WI-FI Direct 是不错的选择,但这仅适用于 Android 4.0 及更高版本

为了在 4.0 以下运行某些东西,您将不得不使用 3rd 方库。我知道 Qualcomm 有一个名为 alljoyn 的库,但不确定它有多好。

【讨论】:

  • 很好,但我需要 VOIP 应用程序 :)
  • 一旦你有了连接,你就可以在它上面运行任何你想要的服务。如果您正在寻找已经内置 p2p 功能的 voip,那么我认为您不会找到它。
  • 其实我需要点到多点能力:)
  • @CostaMirkin wifi-direct 解决方案应该允许您拥有任意数量的连接。您是否阅读了链接另一端的资源?
【解决方案4】:

我认为您可以在包括 Andriod 在内的多个平台上使用 JITSI 进行 p2p voip 服务。

这些是我对这个项目的发现:-

  1. 不需要任何服务器或互联网连接。
  2. 用户必须在同一个网络下。
  3. 开源。
  4. Android apk 可用,很可能你可以在网站上找到它的代码,或者你可以反编译它。

【讨论】:

    【解决方案5】:

    这是不可能的,因为 VOIP 呼叫通过互联网和 sip 服务器传递。

    例如。如果您想通过 VOIP dailer 从您所在国家/地区拨打电话,您必须需要互联网接入,因为无法通过蓝牙进行通信。

    谢谢。

    【讨论】:

    • 但是如果我只想使用 WIFI 连接的 2 部手机在没有互联网连接的情况下相互通话?
    • 这是不可能的,因为你必须需要一个服务器才能相互通信.....
    • 但它仅适用于 SIP。也许有一些方法可以在 Java vithout SIP 中构建 VOIP 应用程序?
    • 可以在没有 SIP 的情况下构建 VOIP。您只需要创建自己的语音数据传输协议。
    • 根据定义,所有 SIP 用户代理都是服务器。除了 SIP 用户代理本身之外,协议中没有任何要求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    相关资源
    最近更新 更多