# Realize One-to-One Voice Calling

This guide introduces how to implement one-to-one voice calls. The API call sequence of one-to-one voice calls is shown in the figure below:

../../../../_images_en/1-1workflowandroid.jpg

# Handle the Android permissions

Use the checkSelfPermission (opens new window) method to check and get microphone access to the Android mobile device when the activity is turned on.

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

private void requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA}, 1000);
        }
    }
}

# Initialize

Call JCMediaDevice.create (opens new window) and JCCall.create (opens new window) to initialize the modules needed for one-to-one calling:

// Declare object
JCMediaDevice mMediaDevice;
JCCall mCall;

// Initialization function
public boolean initialize(Context context) {
    //1. Media class
    mMediaDevice = JCMediaDevice.create(mClient, new JCMediaDeviceCallback() {
        @Override
        public void onCameraUpdate() {

        }
        @Override
        public void onAudioOutputTypeChange(int i) {

        }
        @Override
        public void onRenderReceived(JCMediaDeviceVideoCanvas jcMediaDeviceVideoCanvas) {

        }
        @Override
        public void onRenderStart(JCMediaDeviceVideoCanvas jcMediaDeviceVideoCanvas) {

        }
    });
    //2. Call class
    mCall = JCCall.create(mClient, mMediaDevice, new JCCallCallback() {
        @Override
        public void onCallItemAdd(JCCallItem jcCallItem) {

        }

        @Override
        public void onCallItemRemove(JCCallItem jcCallItem, int i, String s) {

        }

        @Override
        public void onCallItemUpdate(JCCallItem jcCallItem, JCCallItem.ChangeParam changeParam) {

        }

        @Override
        public void onMessageReceive(String s, String s1, JCCallItem jcCallItem) {

        }

        @Override
        public void onMissedCallItem(JCCallItem jcCallItem) {

        }
    });
}

# Make a call

Call call (opens new window) to initiate a video call, the parameters that need to be filled are:

// Initiate a voice call
mCall.call("userID", isVideo , new JCCall.CallParam("extraParam", "ticket"));

After the call is made, both the caller and the called party will receive the callback onCallItemAdd (opens new window) for the new call, and the call status will change to STATE_PENDING (opens new window) at this time. You can perform logical operations by overriding onCallItemAdd (opens new window):

// 1. Initiate a voice call
mCall.call("userID", isVideo , new JCCall.CallParam("extraParam", "ticket"));

// 2. Override callback
@Override
public void onCallItemAdd(JCCallItem item) {
    // Business logic
    if (item.getDirection() == JCCall.DIRECTION_IN) {
        // If you are the called party
        ...
    }else{
        // If you are the caller
        ...
    }
}

# Answer a call

  1. The called party receives the onCallItemAdd (opens new window) callback, and calls the getVideo (opens new window) in JCCallItem (opens new window) in the callback to obtain the video attribute to determine whether it is an incoming video call or a voice call, and then make corresponding processing:

    @Override
    public void onCallItemAdd(JCCallItem item) {
        // 1. If it is an incoming video call and it is ringing
        if (item.getDirection() == JCCall.DIRECTION_IN && !item.getVideo()) {
            // 2. Make corresponding processing, such as "ringing" on the interface
            ...
        }
    }
    
  2. Call answer (opens new window) to answer the call:

    mCall.answer(item, false);
    

After the call is answered, the call status changes to STATE_CONNECTING.

TIP

If you want to reject the call at this time, please call the interface to hang up the call. In this case, after calling hang up, the call state changes to STATE_CANCELED.

# Hang up a call

Both the calling party and the called party can hang up the call.

  1. Call getActiveCallItem (opens new window) to get the currently active call object:

    mCall.getActiveCallItem();
    
  2. Call term (opens new window) to hang up the current active call:

    mCall.term(item, reason, description);
    

Sample code:

// 1. Get the current active call
JCCallItem item = mCall.getActiveCallItem();
// 2. Hang up the current active call
mCall.term(item, JCCall.REASON_NONE, null);
最后更新时间: 1/17/2023, 5:17:17 PM