简体   繁体   English

Android VOIP应用程序无法访问互联网

[英]Android VOIP application without access to internet

I need to develop the VOIP application between 2 android devices. 我需要在两个Android设备之间开发VOIP应用程序。
As I know there is a SIP protocol used for this purpose but it requires registation to SIP server and access to internet for SIP signaling. 据我所知,有一个用于此目的的SIP协议,但它需要注册到SIP服务器并访问互联网以进行SIP信令。
Is any way to create VOIP application in android without internet access? 有没有办法在没有互联网接入的情况下在Android中创建VOIP应用程序?

Of course it is possible! 当然有可能! Why you would need the internet? 为什么你需要互联网? As long as you are both connected to the same network that is fine! 只要你们都连接到同一个网络就好了! Below is the java and xml for a working app. 下面是工作应用程序的java和xml。

On start up it will provide you with your own local port, for example "52022".. this is random every time and unfortunately that can't be helped. 在启动时,它将为您提供您自己的本地端口,例如“52022”..这是随机的每次,不幸的是,这是无法帮助的。 We then enter the IP address of the other phone and THEIR randomly generated port number and press connect. 然后我们输入另一部电话的IP地址和随机生成的端口号,然后按连接。 They do exactly the same and BAM you're connected :) This test app obviously requires you to be close by to exchange port numbers, but in my proper app I was easily able to request each port number before connecting. 它们做的完全相同而且你连接的BAM :)这个测试应用程序显然要求你靠近交换端口号,但在我正确的应用程序中,我很容易在连接之前请求每个端口号。 Hope this helps! 希望这可以帮助!

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>

EDIT: The IP address method stopped working at API 22, use below code: 编辑: 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;
}

actually SIP clients can talk peer-to-peer, they just need to know their IP addresses and UDP ports where they listen to SIP messages. 实际上,SIP客户端可以通过对等方式进行通信,他们只需要知道他们收听SIP消息的IP地址和UDP端口。

You can play around with normal SIP clients on two comuters (X-Lite for Windows, Twinkle for Linux, and some others exist too) and try establishing a call between them without server registration. 您可以在两台计算机上使用普通的SIP客户端(X-Lite for Windows,Twinkle for Linux,以及其他一些也存在)并尝试在它们之间建立呼叫而无需注册服务器。 It's quite possible. 这很有可能。

Also you can run a minimalistic SIP server somewhere in local LAN. 您还可以在本地LAN中的某个位置运行简约SIP服务器。 For example, FreeSWITCH can be minimized to a quite tiny footprint. 例如,FreeSWITCH可以最小化到非常小的空间。

It is not possible because VOIP call Pass through internet and via sip server. 这是不可能的,因为VOIP呼叫通过互联网和通过SIP服务器。

for Example . 例如 。 if you want to call outside from your country via VOIP dailer, you must need internet access because it is not possible to communicate via Bluetooth. 如果您想通过VOIP dailer从您所在的国家/地区拨打电话,您必须要访问互联网,因为无法通过蓝牙进行通信。

Thanks. 谢谢。

OK so if you are looking for some peer-2-peer communications, I think wifi is the way to go (better distance and speeds). 好的,如果你正在寻找一些对等的2对等通信,我认为无线路是可行的方式(更好的距离和速度)。 If you can develop for only newer versions of Android then WI-FI Direct is the way to go, but that will only work on Android 4.0 and above 如果你只能开发更新版本的Android,那么WI-FI Direct是可行的方法,但这只适用于Android 4.0及更高版本

In order to have something run on below 4.0 you are going to have to go with a 3rd party library. 为了在4.0以下运行某些东西,你将不得不使用第三方库。 I know Qualcomm has a library called alljoyn , but not sure how good it is. 我知道Qualcomm有一个名为alljoyn的库,但不确定它有多好。

I think you can use JITSI for p2p voip service on multiple platforms including Andriod. 我想你可以在包括Andriod在内的多个平台上使用JITSI进行p2p voip服务。

These are my findings about this project:- 以下是我对该项目的调查结果: -

  1. Do not need any server or internet connectivity. 不需要任何服务器或互联网连接。
  2. Users must be under a same network. 用户必须位于同一网络中。
  3. Open Source. 开源。
  4. Android apk is available, most probably you can find it code on website or you can de-compile it. Android apk可用,很可能你可以在网站上找到它的代码,或者你可以解编译它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM