Android SIP呼叫建立但没有音频

时间:2016-08-03 14:43:24

标签: java android sip voip

我正在为Android开发SIP客户端并且有问题。问题是我连接两个客户端时没有音频。我正在使用的服务器是www.minisipserver.com。每次调用SipAudioCall.Listener中的onCallEstablished方法。

这是扩展BroadcastReceiver的类,它正在侦听调用。 `

package uk.co.tbw.sip.calling;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipProfile;

import uk.co.tbw.utils.TBWLogger;

public class IncomingCallReceiver extends BroadcastReceiver {


    @Override
    public void onReceive(Context context, Intent intent) {
        SipAudioCall incomingCall = null;

        try {

            Call callActivity = (Call) context;

            SipAudioCall.Listener listener = new myListener(context);

            incomingCall = callActivity.mManager.takeAudioCall(intent, listener);
            incomingCall.startAudio();
            callActivity.mAudioCall = incomingCall;
            callActivity.updateStatus(incomingCall);


        } catch (SipException e) {
            if (incomingCall != null) {
                incomingCall.close();
                e.printStackTrace();
            }
        }
    }

    class myListener extends SipAudioCall.Listener {
        private Context context;

        public myListener(Context context) {
            this.context = context;
        }

        @Override
        public void onRinging(SipAudioCall call, SipProfile caller) {
            try {
                call.answerCall(30);
            } catch (SipException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onReadyToCall(SipAudioCall call) {
            TBWLogger.d("IncomingCallReceiver.java onReadyToCall : " + call.toString());
        }

        @Override
        public void onCalling(SipAudioCall call) {
            TBWLogger.d("IncomingCallReceiver.java onCalling : " + call.toString());
        }

        @Override
        public void onRingingBack(SipAudioCall call) {
            TBWLogger.d("IncomingCallReceiver.java onRingingBack : " + call.toString());
        }

        @Override
        public void onCallEstablished(SipAudioCall call) {
            TBWLogger.d("IncomingCallReceiver.java onCallEstablished : " + call.toString());
            if (call.isInCall()) {
                TBWLogger.d("IncomingCallReceiver.java isInCall : " + call.toString());
            }
            if (call.isOnHold()) {
                TBWLogger.d("IncomingCallReceiver.java isOnHold : " + call.toString());
            }
            if (call.isMuted()) {
                TBWLogger.d("IncomingCallReceiver.java isMuted : " + call.toString());
            }

            call.startAudio();
        }

        @Override
        public void onCallEnded(SipAudioCall call) {
            TBWLogger.d("IncomingCallReceiver.java onCallEnded : " + call.toString());
        }

        @Override
        public void onCallBusy(SipAudioCall call) {
            TBWLogger.d("IncomingCallReceiver.java onCallBusy : " + call.toString());
        }

        @Override
        public void onCallHeld(SipAudioCall call) {
            TBWLogger.d("IncomingCallReceiver.java onCallHeld : " + call.toString());
        }

        @Override
        public void onError(SipAudioCall call, int errorCode, String errorMessage) {
            TBWLogger.d("IncomingCallReceiver.java IncomingCallReceiver.java onError : " + call.toString() + "; errorCode: " + errorCode + "; errorMessage: " + errorMessage);
        }

        @Override
        public void onChanged(SipAudioCall call) {
            TBWLogger.d("IncomingCallReceiver.java onReadyToCall : " + call.toString());
        }
    }


}

`

Call.java活动

package uk.co.tbw.sip.calling;

import android.app.Dialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.net.sip.SipRegistrationListener;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.c77.androidstreamingclient.lib.rtp.RtpMediaDecoder;


import java.text.ParseException;

import uk.co.tbw.R;
import uk.co.tbw.utils.TBWLogger;

public class Call extends AppCompatActivity {

    public static final int REQUEST_PERMISSION_CODE = 1567;
    public String mSipAddress = null;

    public SipManager mManager = null;
    public SipProfile mProfile = null;
    public SipAudioCall mAudioCall = null;
    public IncomingCallReceiver mCallReceiver;

    private static final int CALL_ADDRESS = 1;
    private static final int SET_AUTH_INFO = 2;
    private static final int UPDATE_SETTINGS_DIALOG = 3;
    private static final int HANG_UP = 4;

    private RtpMediaDecoder rtpMediaDecoder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Button callBtn = (Button) findViewById(R.id.answer_btn);
        Button closeBtn = (Button) findViewById(R.id.close_btn);

        SurfaceView view = new SurfaceView(this);

        rtpMediaDecoder = new RtpMediaDecoder(view);
        rtpMediaDecoder.start();

        callBtn.setOnClickListener(v -> {
            EditText textField = (EditText) findViewById(R.id.userToCallEditText);
            mSipAddress = textField.getText().toString();
            initiateCall();
        });

        closeBtn.setOnClickListener(v -> {
            if (mAudioCall != null) {
                try {
                    mAudioCall.endCall();
                    TBWLogger.d("Call.java endCall");
                } catch (SipException e) {
                    Log.d("WalkieTalkieActivity/onOptionsItemSelected",
                            "Error ending call.", e);
                }
                mAudioCall.close();
            }
        });


        IntentFilter filter = new IntentFilter();
        filter.addAction("android.SipDemo.INCOMING_CALL");

        mCallReceiver = new IncomingCallReceiver();
        this.registerReceiver(mCallReceiver, filter);


        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }


    private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", okListener)
                .create()
                .show();
    }


    @Override
    protected void onStart() {
        super.onStart();
        initializeManager();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mAudioCall != null) {
            mAudioCall.close();
        }

        closeLocalProfile();

        if (mCallReceiver != null) {
            this.unregisterReceiver(mCallReceiver);
        }
        rtpMediaDecoder.release();
    }

    @Override
    protected void onStop() {
        rtpMediaDecoder.release();
        super.onStop();
    }

    private void closeLocalProfile() {
        if (mManager == null) {
            return;
        }

        try {
            if (mProfile != null) {
                mManager.close(mProfile.getUriString());
            }
        } catch (SipException e) {
            Log.d("CallActivity/onDestroy", "Failed to close local profile.", e);
        }
    }

    private void initializeManager() {
        TBWLogger.d("initializeManager()");
        if (mManager == null) {
            mManager = SipManager.newInstance(this);
        }

        initializeLocalProfile();
    }

    private void initializeLocalProfile() {
        TBWLogger.d("initializeLocalProfile");
        if (mManager == null) {
            return;
        }

        if (mProfile != null) {
            closeLocalProfile();
        }

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        String username = preferences.getString("namePref", "");
        String domain = preferences.getString("domainPref", "");
        String password = preferences.getString("passPref", "");

        if (username.length() == 0 || domain.length() == 0 || password.length() == 0) { //|| password.length() == 0
            showDialog(UPDATE_SETTINGS_DIALOG);
            return;
        }

        try {
            TBWLogger.d("Building new sipProfile");
            SipProfile.Builder builder = new SipProfile.Builder(username, domain);
            builder.setPassword(password);
            mProfile = builder.build();

            Intent intent = new Intent();
            intent.setAction("android.SipDemo.INCOMING_CALL");

            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
            mManager.open(mProfile, pendingIntent, new SipRegistrationListener() {
                @Override
                public void onRegistering(String localProfileUri) {
                    TBWLogger.d("onRegistering");
                    updateStatus("Registering with SIP Server...");
                }

                @Override
                public void onRegistrationDone(String localProfileUri, long expiryTime) {
                    TBWLogger.d("onRegistrationDone");
                    updateStatus("Ready");
                }

                @Override
                public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage) {
                    TBWLogger.d("onRegistrationFailed:" + " errorMessage:" + errorMessage + " errorCode:" + errorCode
                            + " localProfile:" + localProfileUri);
                    updateStatus("Registration failed.  Please check settings.");
                }
            });

        } catch (ParseException e) {
            updateStatus("Connection Error.");
            e.printStackTrace();
        } catch (SipException e) {
            updateStatus("Connection Error.");
            e.printStackTrace();
        }
    }

    public void initiateCall() {
        updateStatus(mSipAddress);

        try {
            SipAudioCall.Listener listener = new SipAudioCall.Listener() {

                @Override
                public void onReadyToCall(SipAudioCall call) {
                    TBWLogger.d("Call.java  onReadyToCall: " + call);
                }

                @Override
                public void onRingingBack(SipAudioCall call) {
                    TBWLogger.d("Call.java  onRingingBack: " + call);
                }

                @Override
                public void onCallBusy(SipAudioCall call) {
                    TBWLogger.d("Call.java  onCallBusy: " + call);
                }

                @Override
                public void onCallHeld(SipAudioCall call) {
                    TBWLogger.d("Call.java  onCallHeld: " + call);
                }

                @Override
                public void onChanged(SipAudioCall call) {
                    TBWLogger.d("Call.java  onChanged: " + call);
                }

                @Override
                public void onCallEstablished(SipAudioCall call) {
//                    AudioManager audio =  (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//                    audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
//                    AudioGroup audioGroup = new AudioGroup();
//                    audioGroup.setMode(AudioGroup.MODE_NORMAL);
//                    AudioStream audioStream = null;
//                    try {
//                        audioStream = new AudioStream(InetAddress.getByAddress(IncomingCallReceiver.getLocalIPAddress()));
//                    } catch (SocketException e) {
//                        e.printStackTrace();
//                    } catch (UnknownHostException e) {
//                        e.printStackTrace();
//                    }
//                    audioStream.setCodec(AudioCodec.PCMU);
//                    audioStream.setMode(RtpStream.MODE_NORMAL);
//                    //set receiver(vlc player) machine ip address(please update with your machine ip)
//                    try {
//                        audioStream.associate(InetAddress.getByAddress(new byte[] {(byte)192, (byte)168, (byte)1, (byte)19 }), 22222);
//                    } catch (UnknownHostException e) {
//                        e.printStackTrace();
//                    }
//                    audioStream.join(audioGroup);


                    //call.setSpeakerMode(true);
                    call.startAudio();
//                    if (call.isMuted()) {
//                        call.toggleMute();
//                    }
                    updateStatus(call);

                    mAudioCall.startAudio();
                    //mAudioCall.setSpeakerMode(true);
                    TBWLogger.d("Call.java onCallEstablished(): ");
                }

                @Override
                public void onRinging(SipAudioCall call, SipProfile caller) {
                    Toast.makeText(Call.this, "Calling", Toast.LENGTH_LONG).show();
                    try {
                        call.answerCall(30);
                    } catch (SipException e) {
                        e.printStackTrace();
                    }
                    TBWLogger.d("Call.java onRinging(): ");
                }

                @Override
                public void onCalling(SipAudioCall call) {
                    Toast.makeText(Call.this, "Calling", Toast.LENGTH_LONG).show();
                    TBWLogger.d("Call.java onRinging(): ");
                }

                @Override
                public void onCallEnded(SipAudioCall call) {
                    updateStatus("Ready");
                    TBWLogger.d("Call.java onCallEnded(): ");
                }

                @Override
                public void onError(SipAudioCall call, int errorCode, String errorMessage) {
                    TBWLogger.d("Call.java onError: errorCode: " + errorCode + "; errorMessage: " + errorMessage);
                    updateStatus("Call.java onError: errorCode: " + errorCode + "; errorMessage: " + errorMessage);
                }
            };

            mAudioCall = mManager.makeAudioCall(mProfile.getUriString(), mSipAddress, listener, 30);

        } catch (SipException e) {
            Log.i("InitiateCall", "Error when trying to close manager", e);
            if (mProfile != null) {
                try {
                    mManager.close(mProfile.getUriString());
                } catch (SipException e1) {
                    Log.i("InitiateCall", "Error when trying to close manager", e1);
                    e1.printStackTrace();
                }
            }
            if (mAudioCall != null) {
                mAudioCall.close();
            }
        }
    }

    public void updateStatus(String s) {
        this.runOnUiThread(() -> {
            TextView label = (TextView) findViewById(R.id.label);
            label.setText(s);
        });
    }

    public void updateStatus(SipAudioCall s) {
        String userName = s.getPeerProfile().getDisplayName();
        if (userName == null) {
            userName = s.getPeerProfile().getUserName();
        }
        updateStatus(userName + "@" + s.getPeerProfile().getSipDomain());
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, SET_AUTH_INFO, 0, "Edit your SIP Info");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case SET_AUTH_INFO:
                updatePreferences();
                break;
        }
        return true;
    }

    //TODO: check the break statements
    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case CALL_ADDRESS:

                LayoutInflater factory = LayoutInflater.from(this);
                final View textBoxView = factory.inflate(R.layout.call_address_dialog, null);
                return new AlertDialog.Builder(this)
                        .setTitle("Call Someone")
                        .setView(textBoxView)
                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                EditText textField = (EditText) (textBoxView.findViewById(R.id.call_address_edit));
                                mSipAddress = textField.getText().toString();
                                initiateCall();
                            }
                        })
                        .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        }).create();

            case UPDATE_SETTINGS_DIALOG:
                return new AlertDialog.Builder(this)
                        .setMessage("Please update your SIP Account Settings.")
                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                updatePreferences();
                            }
                        })
                        .setNegativeButton(
                                android.R.string.cancel, new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        // Noop.
                                    }
                                })
                        .create();
        }

        return null;
    }

    private void updatePreferences() {
        Intent settingsActivity = new Intent(getBaseContext(), SipSetting.class);
        startActivity(settingsActivity);

    }
}
`

Manifest`

      <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission android:name="android.permission.USE_SIP" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
        <uses-permission android:name="android.permission.CONFIGURE_SIP" />
        <uses-permission android:name="android.software.sip" android:required="true" />
        <uses-permission android:name="android.software.sip.voip" android:required="true" />
        <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

        <uses-permission android:name="android.permission.CONFIGURE_SIP" />
        <uses-permission android:name="android.permission.CALL_PHONE"/>
        <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
        <uses-permission android:name="android.permission.WAKE_LOCK"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.hardware.wifi" android:required="true"/>
        <uses-permission android:name="android.software.sip.voip" android:required="true" />

        <uses-permission android:name="android.hardware.microphone" android:required="true"/>
        <uses-permission android:name="android.hardware.sip.voip" android:required="true" />
        <uses-permission android:name="android.hardware.telephony" android:required="false" />

 <application ...
            <receiver android:name=".sip.calling.IncomingCallReceiver" android:label="Call Receiver"/>
            <activity
                android:name=".sip.calling.Call"
                android:configChanges="orientation|keyboardHidden"
                android:theme="@style/AppTheme.NoActionBar">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
                <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value="uk.co.tbw.MainActivity"/>
            </activity>
</application>

`

1 个答案:

答案 0 :(得分:0)

您使用什么库进行SIP信令?

在某些图书馆中,您必须在建立时将麦克风和扬声器分配给通话。

相关问题