1

ここ数日、私は JAIN SIP を Android で動かそうとしました。Java アプリケーションで正常に動作するコードをいくつか取り、それを Android アプリケーションに移植しました。

私がチェックしました:

  • マニフェストの権限 (INTERNET / ALL)
  • JAIN SIP API は正常に動作します (stackoverflow の他のスレッドがそれに焦点を当てています)。
  • 通信は、MainThread ではなく、独自のスレッドで実行されます。
  • IP は有効です。
  • Android をプラットフォームとして使用せず、Ubuntu を使用している場合、コードは機能します。
  • Android 4.0.3以降を試しました。

私のコード:

public class MainActivity extends Activity implements SipListener {

private static final String LOG = "JAIN";
private static final int PORT = 5060;
private SipFactory mSipFactory;
private AddressFactory mAddressFactory;
private MessageFactory mMessageFacory;
private HeaderFactory mHeaderFactory;
private SipStack mSipStack;
private SipProvider mSipProvider;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new Thread(new Runnable(){

        @Override
        public void run() {
            try {
                // Create factories
                mSipFactory = SipFactory.getInstance();
                mAddressFactory = mSipFactory.createAddressFactory();
                mMessageFacory = mSipFactory.createMessageFactory();
                mHeaderFactory = mSipFactory.createHeaderFactory();

                // Create the SipStack
                Properties properties = new Properties();
                properties.setProperty("javax.sip.STACK_NAME","Stack");
                mSipStack = mSipFactory.createSipStack(properties);

                // Create the SipProvider 
                String localIP = InetAddress.getLocalHost().getHostAddress();
                ListeningPoint listeningPoint = mSipStack
                        .createListeningPoint(localIP, PORT, "udp");
                mSipProvider = mSipStack.createSipProvider(listeningPoint);
                mSipProvider.addSipListener(MainActivity.this);

                // Create addresses and via header for the request
                Address fromToAddress = mAddressFactory
                        .createAddress("sip:192.168.0.198");
                Address contactAddress = mAddressFactory
                        .createAddress("sip:me@192.168.0.195");
                ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
                ViaHeader myViaHeader = mHeaderFactory
                        .createViaHeader("me.bla.com", PORT, "udp", "tlf64");
                viaHeaders.add(myViaHeader);

                // Build the request
                final Request request = mMessageFacory.createRequest(
                        mAddressFactory.createAddress("sip:192.168.0.195:9876").getURI(), 
                        "REGISTER",
                        mHeaderFactory.createCallIdHeader("12345678"),
                        mHeaderFactory.createCSeqHeader(1234l, "REGISTER"), 
                        mHeaderFactory.createFromHeader(fromToAddress, "sdf6"),
                        mHeaderFactory.createToHeader(fromToAddress, null), 
                        viaHeaders, 
                        mHeaderFactory.createMaxForwardsHeader(70));

                // Add the contact header
                request.addHeader(mHeaderFactory.createContactHeader(contactAddress));

                // Print the request
                System.out.println(request.toString());

                // Send the request --- triggers an IOException
                mSipProvider.sendRequest(request);
            } catch (Exception e) {
                Log.d(LOG, Log.getStackTraceString(e));
            }
        }}).start();
}

StackTrace でわかるように、IOException が発生します。

javax.sip.SipException: IO Exception occured while Sending Request
at gov.nist.javax.sip.SipProviderImpl.sendRequest(SipProviderImpl.java:722)
at com.example.jainsiptest.MainActivity$1.run(MainActivity.java:97)
at java.lang.Thread.run(Thread.java:856)
 Caused by: java.net.SocketException: sendto failed: EINVAL (Invalid argument)
at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506)
at libcore.io.IoBridge.sendto(IoBridge.java:475)
at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182)
at java.net.DatagramSocket.send(DatagramSocket.java:284)
at gov.nist.javax.sip.stack.UDPMessageChannel.sendMessage(UDPMessageChannel.java:724)
at gov.nist.javax.sip.stack.MessageChannel.sendMessage(MessageChannel.java:222)
at gov.nist.javax.sip.SipProviderImpl.sendRequest(SipProviderImpl.java:711)
... 2 more
 Caused by: libcore.io.ErrnoException: sendto failed: EINVAL (Invalid argument)
at libcore.io.Posix.sendtoBytes(Native Method)
at libcore.io.Posix.sendto(Posix.java:151)
at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
at libcore.io.IoBridge.sendto(IoBridge.java:473)
... 7 more

java.net.SocketException: sendto failed: EINVAL (Invalid argument)

同じ引数でUbuntuではスローされません。

それを修正する方法はありますか?助けてくれてありがとう!

4

2 に答える 2

1

Android OS は、指定された文字列を Ubuntu OS とは異なる方法で処理しているようです。どうしてか分かりません。


結局、JAIN SIP の代わりに MjSip を使用して問題を解決しました。

SIP に加えて RTP、SDP などの機能が必要なので、MjSip 1.6 を使用するオープン ソースの Android アプリSipdroidを自分の要求に合うように変更することにしました。

  1. そのためには、まずコードを取得します。

  2. プロジェクトを Eclipse にインポートします: [ファイル] -> [インポート] -> [既存の Android コードをワークスペースに]。

  3. API レベルなどを考慮して、要件を満たす新しい Android プロジェクトを作成します。

  4. <uses-permission android:name="android.permission.INTERNET" />プロジェクトのマニフェストに追加します。

  5. 以下を除くすべてのパッケージを Sipdroid プロジェクトからプロジェクトにコピーします。

    • org.sipdroid.codecs および org.sipdroid.media (これはまだ必要ありませんが、後で必要になるかもしれません)
    • org.sipdroid.sipua およびサブパッケージ。
  6. 壊れた参照を削除またはコメントします。

  7. REGISTER をサーバーに送信するには、以下のコードを参照してください。

  8. android.util.Log指定されたコードの代わりに使用して、ログ メカニズムによってスローされる例外を修正します。最後に、NullPointerException をトリガーするフラッシュ コマンドを削除またはコメントします。

それでおしまい。

import org.zoolu.sip.address.NameAddress;
import org.zoolu.sip.message.Message;
import org.zoolu.sip.message.MessageFactory;
import org.zoolu.sip.provider.SipProvider;
import org.zoolu.sip.provider.SipStack;
import org.zoolu.sip.transaction.TransactionClient;
import org.zoolu.sip.transaction.TransactionClientListener;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity implements TransactionClientListener{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new Thread(new Runnable(){

        @Override
        public void run() {
            try{
                SipStack.init();

                SipProvider sipProvider = new SipProvider(
                        "192.168.0.198", 5060, new String[]{"udp"}, null);
                NameAddress toAddress = new NameAddress(
                        "sip:192.168.0.195:9876");
                NameAddress fromAddress = new NameAddress(
                        "sip:192.168.0.198:9876");

                Message message = MessageFactory.createRegisterRequest(
                        sipProvider, 
                        toAddress, 
                        fromAddress, 
                        fromAddress, 
                        null, 
                        null);

                TransactionClient t = new TransactionClient(
                        sipProvider, 
                        message,
                        MainActivity.this);

                t.request();

            }catch(Exception e){
                Log.d("MYSIP", Log.getStackTraceString(e));
            }
        }}).start();
}

// Interface methods

}
于 2013-01-08T15:52:16.273 に答える
0

次のように取得する代わりにlocalIPAddress:

String localIP = InetAddress.getLocalHost().getHostAddress();

NetworkInterfaceまたはを使用して IP アドレスを取得しますWifiManager

于 2013-06-02T01:41:58.327 に答える