2016-08-03 31 views
2

Ich entwickle SIP-Client für Android und habe ein Problem. Das Problem ist, dass ich kein Audio habe, während zwei Clients verbunden sind. Der Server, den ich verwende, ist www.minisipserver.com. Die Methode onCallEstablished vom SipAudioCall.Listener wird jedes Mal aufgerufen.Android SIP Call etabliert, aber kein Audio

Dies ist die Klasse, die BroadcastReceiver erweitert, der auf den Anruf wartet. `

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 Aktivität

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> 

`

Antwort

0

Welche Bibliothek verwenden Sie für die SIP-Signalisierung?

In einigen Bibliotheken müssen Sie dem Anruf das Mikrofon und den Lautsprecher zuweisen, wenn es eingerichtet ist.

+0

Ich verwende https://developer.android.com/guide/topics/connectivity/sip.html – emchoko