Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Поля ввода, необходимые для установления SIP-соединения

  • 'WCS URL' , где 192.168.2.104 - адрес WCS-сервера
  • 'SIP Login'- SIP имя пользователя
  • 'SIP Password' - пароль
  • 'SIP Domain' - адрес SIP-доменсервера
  • 'SIP port' - порт

В поле 'Callee' вводится SIP имя вызываемого пользователя вызываемого.
При нажатии на кнопку Connect/Disconnect устанавливается/закрывается SIP-соединение.
При нажатии на кнопку Call/Hangup делается/завершается звонок.
Кнопка Hold/Unhold используется для удержания/снятия с удержания звонка.

Image RemovedImage Added

Работа с кодом примера

Для разбора кода возьмем класс PhoneMinActivity.java примера phone-min, который доступен для скачивания в соответствующей сборке 1.1.0.1.3855.

1. Инициализация API.

Flashphoner.init() код code

Code Block
languagejava
themeRDark
Flashphoner.init(this);

...

Flashphoner.createSession() код code

Методу передается объект SessionOptions с URL WCS-сервераConnection с параметрами для регистрации на SIP сервере.

Code Block
languagejava
themeRDark
SessionOptions sessionOptions = new SessionOptions(mWcsUrlView.getText().toString());
session = Flashphoner.createSession(sessionOptions);

3. Подключение к серверу.

Session.connect() . код code

Методу передается объект Connection с параметрами SIP-соединения

Code Block
languagejava
themeRDark
Connection connection = new Connection();
connection.setSipLogin(mSipLoginView.getText().toString());
connection.setSipPassword(mSipPasswordView.getText().toString());
connection.setSipDomain(mSipDomainView.getText().toString());
connection.setSipOutboundProxy(mSipDomainView.getText().toString());
connection.setSipPort(Integer.parseInt(mSipPortView.getText().toString()));
connection.setSipRegisterRequired(mSipRegisterRequiredView.isChecked());
connection.setKeepAlive(true);
session.connect(connection);

4. Получение от сервера события, подтверждающего успешное соединение.

Session.onConnected(), Session.getAuthToken() код code

...

Сохраняется токен сессии для дальнейших подключений к этой сессии на сервере

Code Block
languagejava
themeRDark
            @Override
            public void onConnected(final Connection connection) {
                runOnUiThread(new Runnable() {
         @Override
        public void run() {@Override
            mConnectButton.setText(R.string.action_disconnect);        public void run() {
            mConnectButton.setTag(R.string.action_disconnect);
            mConnectButton.setEnabled(true);...
            if (!mSipRegisterRequiredView.isChecked()) {
          String token     mConnectStatus.setText(connection.getStatus()= connection.getAuthToken();
                mCallButton.setEnabled(true);
        if (token != null } else&& !token.isEmpty()) {
                mConnectStatus.setText(connection.getStatus() + ". Registering...");
            }
 mAuthTokenView.setText(token);
       }
    });
}

5. Обработка нажатия кнопки Call/Hangup

Button.setOnClickListener() код

Code Block
languagejava
themeRDark
mCallButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
   mConnectTokenButton.setEnabled(true);
             if (mCallButton.getTag() == null || Integer.valueOf(R.string.action_call).equals(mCallButton.getTag())) {
           }
              if ("".equals(mCalleeView.getText().toString())) {      }
                return});
            }
  

5. Обработка нажатия кнопки Call/Hangup

Button.setOnClickListener() code

Code Block
languagejava
themeRDark
mCallButton.setOnClickListener(new OnClickListener() {
    @Override
    public void ActivityCompat.requestPermissions(PhoneMinActivity.this,
onClick(View view) {
        if (mCallButton.getTag() == null || Integer.valueOf(R.string.action_call).equals(mCallButton.getTag())) {
        new String[]{Manifest.permission.RECORD_AUDIO},    if ("".equals(mCalleeView.getText().toString())) {
                  CALL_REQUEST_CODE)return;
            ...}
          } else { ActivityCompat.requestPermissions(PhoneMinActivity.this,
            mCallButton.setEnabled(false);
      new String[]{Manifest.permission.RECORD_AUDIO},
              call.hangup(    CALL_REQUEST_CODE);
            call...
 = null;
      } else }{
         View currentFocus = getCurrentFocusmCallButton.setEnabled(false);
        if  (currentFocus != null) { call.hangup();
            InputMethodManager inputManagercall = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
null;
        }
        View inputManager.hideSoftInputFromWindow(currentFocus.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS)currentFocus = getCurrentFocus();
        }
if (currentFocus != null) }
});

6. Исходящий звонок.

Session.createCall(), Call.call() код

При создании в метод session.createCall() передается объект CallOptions с параметрами:

...

{
            InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            inputManager.hideSoftInputFromWindow(currentFocus.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }
});

6. Исходящий звонок.

Session.createCall(), Call.call() code

При создании в метод session.createCall() передается объект CallOptions с параметрами:

  • SIP логин вызываемого аккаунта
  • настройки аудио
  • дополнительные параметры сообщения SIP INVITE
case CALL_REQUEST_CODE: { if (grantResults.length == 0 ||
Code Block
languagejava
themeRDark
case CALL_REQUEST_CODE: {
    if (grantResults.length == 0 ||
          grantResults[0] != PackageManager.PERMISSION_GRANTED) {
        Log.i(TAG, "Permission has been denied by user");
    } else {
        mCallButton.setEnabled(false);
        /**
          * Get call options from the callee text field
          */
        CallOptions callOptions = new CallOptions(mCalleeView.getText().toString());
        AudioConstraints audioConstraints = callOptions.getConstraints().getAudioConstraints();
        MediaConstraints mediaConstraints = audioConstraints.getMediaConstraints();
        ...
        try {
            Map<String, String> inviteParameters = new Gson().fromJson(mInviteParametersView.getText().toString(),
               new TypeToken<Map<String, String>>() {
               }.getType());
            callOptions.setInviteParameters(inviteParameters);
        } catch (Throwable t) {
            Log.e(TAG, "Invite Parameters have wrong format of json object");
        }
        call = session.createCall(callOptions);
        call.on(callStatusEvent);
        /**
          * Make the outgoing call
          */
        call.call();
        Log.i(TAG, "Permission has been granted by user");
        break;
    }
}

7. Получение от сервера события, сигнализирующего о входящем звонке

Session.onCall() code

Code Block
languagejava
themeRDark
@Override
public void onCall(final Call call) {
    call.on(callStatusEvent);
    /**
      * Display UI alert for the new incoming call
      */
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            AlertDialog.Builder builder = new AlertDialog.Builder(PhoneMinActivity.this);

            builder.setTitle("Incoming call");

            builder.setMessage("Incoming call from '" + call.getCaller() + "'");
            grantResults[0] != PackageManager.PERMISSION_GRANTEDbuilder.setPositiveButton("Answer", new DialogInterface.OnClickListener() {
          Log.i(TAG, "Permission has been denied by user");@Override
    } else {
        mCallButton.setEnabled(false);
  public void onClick(DialogInterface dialogInterface, int i) /**{
          *   Get call options from the callee text field
   PhoneMinActivity.this.call = call;
        */
        CallOptions callOptions = new CallOptions(mCalleeViewActivityCompat.getTextrequestPermissions().toString());PhoneMinActivity.this,
        AudioConstraints audioConstraints = callOptions.getConstraints().getAudioConstraints();
        MediaConstraints mediaConstraints = audioConstraints.getMediaConstraints();
       new String[]{Manifest.permission..RECORD_AUDIO},
        try {
            Map<String, String> inviteParameters = new Gson().fromJson(mInviteParametersView.getText().toString(), INCOMING_CALL_REQUEST_CODE);
               new TypeToken<Map<String, String>>() { }
               }.getType()});
            builder.setNegativeButton("Hangup", new callOptionsDialogInterface.setInviteParametersOnClickListener(inviteParameters); {
          }   catch (Throwable t) {@Override
             Log.e(TAG, "Invite Parameters havepublic wrongvoid format of json object");
onClick(DialogInterface dialogInterface, int i) {
          }
        call = sessioncall.createCallhangup(callOptions);
          call.on(callStatusEvent);
        /**
  incomingCallAlert = null;
      * Make the outgoing call
      }
    */
        call.call(});
        Log.i(TAG, "Permission has been grantedincomingCallAlert by user"= builder.show();
        break;}
    });
}

7. Получение от сервера события, сигнализирующего о входящем звонке

Session.onCall() код8. Ответ на входящий звонок.

Call.answer() code

@Override public void onCall(final Call call) {
Code Block
languagejava
themeRDark
RDark
case INCOMING_CALL_REQUEST_CODE: {
    if (grantResults.length == 0 ||
           grantResults[0] != PackageManager.PERMISSION_GRANTED) {
        call.onhangup(callStatusEvent);
    /**
    incomingCallAlert = *null;
 Display UI alert for the new incoming call
      */ Log.i(TAG, "Permission has been denied by user");
    runOnUiThread(new Runnable()} else {
        @OverridemCallButton.setText(R.string.action_hangup);
        public void run() {
mCallButton.setTag(R.string.action_hangup);
        mCallButton.setEnabled(true);
     AlertDialog.Builder builder = new AlertDialogmCallStatus.BuildersetText(PhoneMinActivitycall.thisgetStatus());

            builder.setTitle("Incoming call"call.answer();

        incomingCallAlert = null;
  builder.setMessage("Incoming call from '" + call.getCaller() + "'");
   Log.i(TAG, "Permission has been granted by user");
    builder.setPositiveButton("Answer", new DialogInterface.}
}

9. Удержание и возобновление звонка.

Call.hold(), Call.unhold() code

Code Block
languagejava
themeRDark
mHoldButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View      @Overrideview) {
        if (mHoldButton.getTag() == null     public void onClick(DialogInterface dialogInterface, int i|| Integer.valueOf(R.string.action_hold).equals(mHoldButton.getTag())) {
                    PhoneMinActivity.this.call = callcall.hold();
                    ActivityCompat.requestPermissions(PhoneMinActivity.this,mHoldButton.setText(R.string.action_unhold);
               mHoldButton.setTag(R.string.action_unhold);
        }   new String[]{Manifest.permission.RECORD_AUDIO},else {
            call.unhold();
              INCOMING_CALL_REQUEST_CODEmHoldButton.setText(R.string.action_hold);
                }mHoldButton.setTag(R.string.action_hold);
        }

    }
});
            builder.setNegativeButton("Hangup", new DialogInterface.

10. Посылка тонального сигнала

Call.sendDTMF() code

Code Block
languagejava
themeRDark
mDTMF = (EditText) findViewById(R.id.dtmf);
mDTMFButton = (Button) findViewById(R.id.dtmf_button);
mDTMFButton.setOnClickListener(new OnClickListener() {
@Override
    public void onClick(View          @Overrideview) {
        if (call != null) {
    public void onClick(DialogInterface dialogInterface, int i) {
       call.sendDTMF(mDTMF.getText().toString(), Call.DTMFType.RFC2833);
        }
    }
});

11. Завершение исходящего звонка.

Call.hangup() code

Code Block
languagejava
themeRDark
mCallButton.setEnabled(false);
call.hangup();
call = null;

12. Завершение входящего звонка.

Call.hangup() code

Code Block
languagejava
themeRDark
builder.setNegativeButton("Hangup",                  incomingCallAlert = null;new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialogInterface, int i)   }{
            }call.hangup();
            incomingCallAlert = builder.show()null;
        }
    });
}

8. Ответ на входящий звонок13. Закрытие соединения.

CallSession.answerdisconnect() код code

Code Block
languagejava
themeRDark
case INCOMING_CALL_REQUEST_CODE: {
    if (grantResults.length == 0 ||
mConnectButton.setEnabled(false);
session.disconnect();

14. Подключение к существующей сессии на сервере по токену

Connection.setAuthToken(), Session.connect code

Code Block
languagejava
themeRDark
        mConnectTokenButton.setOnClickListener(new OnClickListener() {
 grantResults[0] != PackageManager.PERMISSION_GRANTED) {
        call.hangup();@Override
        incomingCallAlert = null;
  public void onClick(View v)   Log.i(TAG, "Permission has been denied by user");
{
           } else {
   if (mConnectTokenButton.getTag() == null || mCallButtonInteger.setTextvalueOf(R.string.action_hangup);
_connect_token).equals(mConnectTokenButton.getTag())) {
                    connectWithToken  mCallButton.setTag(R.string.action_hangup);
= true;
             mCallButton.setEnabled(true);
       String authToken = mCallStatusmAuthTokenView.setTextgetText(call).getStatustoString());
         call.answer();
            incomingCallAlert = null;if (authToken.isEmpty()) {
        Log.i(TAG, "Permission has been granted by user");
    }
}

9. Удержание и возобновление звонка.

Call.hold(), Call.unhold() код

Code Block
languagejava
themeRDark
mHoldButton.setOnClickListener(new OnClickListener() {
      return;
     @Override
     public void onClick(View view) {
      }
  if (mHoldButton.getTag() == null || Integer.valueOf(R.string.action_hold).equals(mHoldButton.getTag())) {
            callmConnectButton.holdsetEnabled(false);
            mHoldButton.setText(R.string.action_unhold);
            mHoldButton.setTag(R.string.action_unholdmConnectTokenButton.setEnabled(false);
        } else {
            call.unholdcreateSession();
            mHoldButton.setText(R.string.action_hold);
         Connection connection = new mHoldButton.setTag(R.string.action_holdConnection();
             }

    }
});

10. Посылка тонального сигнала

Call.sendDTMF() код

Code Block
languagejava
themeRDark
mDTMF = (EditText) findViewById(R.id.dtmf);
mDTMFButton = (Button) findViewById(R.id.dtmf_button);
mDTMFButton.setOnClickListener(new OnClickListener() {
@Override
    public void onClick(View view) {
 connection.setAuthToken(authToken);
                    connection.setKeepAlive(true);
                 if (call != null) {
 session.connect(connection);
             call.sendDTMF(mDTMF.getText().toString(), Call.DTMFType.RFC2833);
  } else {
    }
    }
});

11. Завершение исходящего звонка.

Call.hangup() код

Code Block
languagejava
themeRDark
mCallButton            mConnectButton.setEnabled(false);
call.hangup();
call = null;

12. Завершение входящего звонка.

Call.hangup() код

Code Block
languagejava
themeRDark
builder.setNegativeButton("Hangup", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialogInterface, int i) {
                    mConnectTokenButton.setEnabled(false);
                    session.disconnect();
                call.hangup();
}
          incomingCallAlert = null;
}
        }
});

13. Закрытие соединения.

Session.disconnect() код

Code Block
languagejava
themeRDark
mConnectButton.setEnabled(false);
session.disconnect();