首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SIP:错误DATA_CONNECTION_LOST

SIP:错误DATA_CONNECTION_LOST
EN

Stack Overflow用户
提问于 2013-12-19 08:29:40
回答 1查看 2K关注 0票数 13

我在android .In中使用本机sip创建了sip应用程序--我在从.In服务器注销帐户方面遇到了问题,每次我在android文档中也看到.I时,都会遇到问题,但是对于这个error.Also,它在in_progress、transaction_terminated等正则迭代器中所面临的各种错误并没有简单的解释,而这些错误在文档中没有正确的解释。这是我的代码:

代码语言:javascript
复制
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.*;
import android.widget.Chronometer;
import android.net.sip.*;
import java.text.ParseException;
import commonUtilities.Prefs;

public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {

    public String sipAddress = null;
    public SipManager manager = null;
    public SipProfile me = null;
    public SipAudioCall call = null;
    public SipErrorCode sipcode;
    public SipException sipexeception;
    public static WalkieTalkieActivity walkiy;

    public static WalkieTalkieActivity getInstance(Context c) {
        if (walkiy == null) {
            walkiy = new WalkieTalkieActivity();
        }
        return walkiy;
    }@
    Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        // "Push to talk" can be a serious pain when the screen keeps turning off.
        // Let's prevent that.
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        Log.e("onCreate", "onCreate");
        initializeManager(this);
    }@
    Override
    public void onStart() {
        super.onStart();
        // When we get back from the preference setting Activity, assume
        // settings have changed, and re-login with new auth info.
        initializeManager(this);
    }@
    Override
    public void onDestroy() {

        super.onDestroy();
        if (call != null) {
            call.close();
        }
        closeLocalProfile();
    }@
    Override
    protected void onResume() {
        // TODO Auto-generated method stub
        initializeManager(this);
        super.onResume();
    }
    public void initializeManager(Context ctx) {


        if (manager == null) {
            Log.e("initialising ", "ini manager");
            manager = SipManager.newInstance(ctx);
        }
        initializeLocalProfile(ctx);
    }

    public void initializeLocalProfile(final Context ctx) {
        if (manager == null) {
            updateStatus("Not Supporting.", ctx);
            Log.e("return", "manager is null ");
            return;
        }

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
        String username = prefs.getString("namePref", Prefs.getUserName(ctx));
        String domain = prefs.getString("domainPref", "255.235.472");
        String password = prefs.getString("passPref", Prefs.getUserPassword(ctx));

        if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
            return;
        }
        try {
            SipProfile.Builder builder = new SipProfile.Builder(username, domain);
            builder.setPassword(password);
            me = builder.build();
            Intent intent = new Intent();
            intent.setAction("android.SipDemo.INCOMING_CALL");
            PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 0, intent, Intent.FILL_IN_DATA);
            manager.open(me, pendingIntent, null);

            if (!manager.isRegistered(me.getUriString())) {
                manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {

                    public void onRegistering(String localProfileUri) {
                        Log.e("Sip restration", "Registering with SIP Server...");
                        updateStatus("Registering with SIP Server...", ctx);
                    }

                    public void onRegistrationDone(String localProfileUri, long expiryTime) {
                        Log.e("Sip restration", "Ready");
                        updateStatus("Ready", ctx);
                    }

                    public void onRegistrationFailed(String localProfileUri, int errorCode,
                        String errorMessage) {
                        Log.e("Registration Error Code ", SipErrorCode.toString(errorCode) + errorCode);
                        updateStatus(errorCode + " " + SipErrorCode.toString(errorCode), ctx);
                    }
                });
            } else {
                Log.e("already register", "already register");
                updateStatus("Ready", ctx);
            }
        } catch (ParseException pe) {
            updateStatus("Connection Error.", ctx);
        } catch (SipException se) {
            updateStatus("Connection error.", ctx);
        }
    }

    public Boolean closeLocalProfile() {
        Log.e("Closing profile", "closing profile " + me.getUriString());

        if (manager == null) {
            return false;
        }
        try {
            if (me != null) {
                Log.e("Unregistering profile", "Un registering profile ");
                manager.unregister(me, null);
                manager.close(me.getUriString());
            }
        } catch (Exception ee) {
            Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
        }
        return false;
    }
    public void initiateCall(String number, final Context ctx, final View v) {

        //      updateStatus(sipAddress);
        Log.d("Number", "" + number);
        sipAddress = number;
        Log.e("initiating call", "initiating call");
        try {
            SipAudioCall.Listener listener = new SipAudioCall.Listener() {@
                Override
                public void onCallBusy(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("buzy", "buzy");
                    super.onCallBusy(call);
                }@
                Override
                public void onCallHeld(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("held", "held");
                    super.onCallHeld(call);
                }@
                Override
                public void onCalling(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("calling", "calling");
                    super.onCalling(call);
                }@
                Override
                public void onChanged(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("changed", "changed");
                    super.onChanged(call);
                }@
                Override
                public void onError(SipAudioCall call, int errorCode,
                    String errorMessage) {
                    // TODO Auto-generated method stub
                    Log.e("call error", "error" + SipErrorCode.toString(errorCode));
                    CallingScreen.fa.finish();
                    super.onError(call, errorCode, errorMessage);

                }@
                Override
                public void onReadyToCall(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("ready to call", "ready to call ");
                    super.onReadyToCall(call);
                }@
                Override
                public void onRinging(SipAudioCall call, SipProfile caller) {
                    // TODO Auto-generated method stub
                    Log.e("ringing", "ringing");

                    super.onRinging(call, caller);
                }@
                Override
                public void onRingingBack(SipAudioCall call) {
                    // TODO Auto-generated method stub
                    Log.e("ringing back", "ringing back");
                    super.onRingingBack(call);
                }@
                Override
                public void onCallEstablished(SipAudioCall call) {
                    Log.e("call established", "call established");
                    call.startAudio();
                    updateTime(true, ctx);
                }@
                Override
                public void onCallEnded(SipAudioCall call) {
                    Log.e("call ended", "call ended");

                    updateTime(false, ctx);
                    CallingScreen.fa.finish();
                }
            };
            Log.e("param 1 ", "" + me.getUriString());
            call = manager.makeAudioCall(me.getUriString(), sipAddress + "@216.245.200.2:5060", listener, 30);
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
            if (me != null) {
                try {
                    closeLocalProfile();
                } catch (Exception ee) {
                    ee.printStackTrace();
                    Log.i("WalkieTalkieActivity/InitiateCall",
                        "Error when trying to close manager.", ee);
                    ee.printStackTrace();
                }
            }
            if (call != null) {
                call.close();
            }
        }
    }
    public void updateStatus(final String status, final Context context) {
        // Be a good citizen.  Make sure UI changes fire on the UI thread.
        this.runOnUiThread(new Runnable() {
            public void run() {
                generateNotification(context, status);
            }
        });
    }
    public void updateTime(final Boolean status, final Context context) {
        // Be a good citizen.  Make sure UI changes fire on the UI thread.
        this.runOnUiThread(new Runnable() {
            public void run() {
                if (status) {
                    CallingScreen.fa.ch = (Chronometer) CallingScreen.fa.findViewById(R.id.time);
                    CallingScreen.fa.ch.setTypeface(CallingScreen.normal);
                    CallingScreen.fa.calling_screen_text.setVisibility(View.GONE);

                    CallingScreen.fa.ch.setVisibility(View.VISIBLE);
                    CallingScreen.fa.ch.start();
                } else {
                    CallingScreen.fa.ch.stop();
                }
            }
        });
    }

    public void updateStatus(SipAudioCall call) {
        String useName = call.getPeerProfile().getDisplayName();
        if (useName == null) {
            useName = call.getPeerProfile().getUserName();
        }
        //      updateStatus(useName + "@" + call.getPeerProfile().getSipDomain());
    }
    public boolean onTouch(View v, MotionEvent event) {
        if (call == null) {
            return false;
        } else if (event.getAction() == MotionEvent.ACTION_DOWN && call != null && call.isMuted()) {
            call.toggleMute();
        } else if (event.getAction() == MotionEvent.ACTION_UP && !call.isMuted()) {
            call.toggleMute();
        }
        return false;
    }
    public void endcall() {
        if (call != null) {
            try {
                call.endCall();
            } catch (SipException se) {
                Log.d("WalkieTalkieActivity/onOptionsItemSelected",
                    "Error ending call.", se);
            }
            call.close();
        }
    }
    public void speaker(Boolean speak) {
        if (call != null)
            call.setSpeakerMode(speak);
    }
    public static void generateNotification(Context context, String message) {
        int icon = R.drawable.ic_launcher;
        long when = System.currentTimeMillis();
        NotificationManager notificationManager = (NotificationManager)
        context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = new Notification(icon, message, when);
        String title = context.getString(R.string.app_name);
        Intent notificationIntent = new Intent(context, Splash_screen.class);
        // set intent so it does not start a new activity
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
            Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent =
            PendingIntent.getActivity(context, 0, notificationIntent, 0);
        notification.setLatestEventInfo(context, title, message, intent);
        notificationManager.notify(0, notification);
    }
    public Boolean isRegistered() {
        if (manager != null && me != null)
            try {
                return manager.isRegistered(me.getUriString());
            } catch (SipException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();

            }
        return false;
    }

}

LOGCAT1

代码语言:javascript
复制
12 - 23 14: 19: 10.930: E / Unregistering profile(32139): Un registering profile
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): Failed to close local profile.
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): android.net.sip.SipException: SipService.createSession() returns null
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at android.net.sip.SipManager.unregister(SipManager.java: 507)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at com.phone91.android.WalkieTalkieActivity.closeLocalProfile(WalkieTalkieActivity.java: 144)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at com.phone91.android.DialerActivity$1$2.onClick(DialerActivity.java: 79)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java: 174)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at android.os.Handler.dispatchMessage(Handler.java: 99)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at android.os.Looper.loop(Looper.java: 155)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at android.app.ActivityThread.main(ActivityThread.java: 5520)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at java.lang.reflect.Method.invokeNative(Native Method)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at java.lang.reflect.Method.invoke(Method.java: 511)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 1029)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 796)
12 - 23 14: 19: 10.990: D / WalkieTalkieActivity / onDestroy(32139): at dalvik.system.NativeStart.main(Native Method)

LOG CAT2 :

代码语言:javascript
复制
12-23 14:53:28.890: E/Unregistering profile(2001): Un registering profile 
12-23 14:53:30.050: E/Registration Error Code(2001): DATA_CONNECTION_LOST-10
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-19 10:28:12

我一直在检查SipDemo示例代码,我假设您在应用程序中使用了这个示例代码,但是在注册过程中也遇到了这个错误。

在检查了Android的源代码(4.1)之后,我发现这是堆栈实现中的一个缺陷。更详细的:

  1. SIP服务注册并打算侦听器来更新连接信息。
  2. 当您尝试注册一个SipRegistrationListener太快(通过使用setRegistrationListener),因为网络信息还没有被更新(没有收到意图),它返回SipErrorCode.DATA_CONNECTION_LOST,但实际上,会话最终被正确注册。

在这种情况下,当您在unregister方法中提供unregister时,此过程将失败。一个丑陋的工作将是等待一段时间的意图,以接受或不提供给听众。

您还将看到,如果将unregister调用替换为setRegistrationLister,仍然会收到相同的错误,因此,您还可以尝试创建一个高级管理器,即在onRegistrationDone回调中,您可以设置一个标志来了解您是否可以关闭配置文件。类似于:

代码语言:javascript
复制
public void updateStatus(final int status, final Context context) {
    if(status == STATUS_OK)
        registered = true;

    // Be a good citizen.  Make sure UI changes fire on the UI thread.
    this.runOnUiThread(new Runnable() {
        public void run() {
            generateNotification(context, statusToString(status));
        }
    });
}

当关闭本地配置文件时:

代码语言:javascript
复制
public Boolean closeLocalProfile() {
    Log.e("Closing profile", "closing profile " + me.getUriString());

    if (manager == null || !registered) {
        return false;
    }
    try {
        if (me != null) {
            Log.e("Unregistering profile", "Un registering profile ");
            manager.unregister(me, null);
            manager.close(me.getUriString());
        }
    } catch (Exception ee) {
        Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
    }
    return false;
}

请注意,我在updateStatus中使用了一个整数,而不是一个字符串,并使用一个助手函数statusToString将状态代码转换为字符串。

正如您可能已经注意到的,这将增加一个额外的管理层,最初,它应该已经在堆栈中,但它不是。我不确定这是否能修复所有返回错误(在检查了源代码之后,我看到了几个可能的错误),但应该会有所帮助。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20676709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档