integration with OpenTok android
@ -1,32 +1,41 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    package="com.example.doctor_app_flutter">
 | 
			
		||||
    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
 | 
			
		||||
    <!--
 | 
			
		||||
         io.flutter.app.FlutterApplication is an android.app.Application that
 | 
			
		||||
         calls FlutterMain.startInitialization(this); in its onCreate method.
 | 
			
		||||
         In most cases you can leave this as-is, but you if you want to provide
 | 
			
		||||
         additional functionality it is fine to subclass or reimplement
 | 
			
		||||
         FlutterApplication and put your custom class here. -->
 | 
			
		||||
    <uses-permission android:name="android.permission.INTERNET"/>
 | 
			
		||||
         FlutterApplication and put your custom class here.
 | 
			
		||||
    -->
 | 
			
		||||
    <uses-permission android:name="android.permission.INTERNET" />
 | 
			
		||||
    <uses-permission android:name="android.permission.CAMERA" />
 | 
			
		||||
 | 
			
		||||
    <application
 | 
			
		||||
        android:name="io.flutter.app.FlutterApplication"
 | 
			
		||||
        android:label="doctor_app_flutter"
 | 
			
		||||
        android:icon="@mipmap/ic_launcher">
 | 
			
		||||
        android:icon="@mipmap/ic_launcher"
 | 
			
		||||
        android:label="doctor_app_flutter">
 | 
			
		||||
        <activity android:name=".VideoCallActivity"></activity>
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name=".MainActivity"
 | 
			
		||||
            android:launchMode="singleTop"
 | 
			
		||||
            android:theme="@style/LaunchTheme"
 | 
			
		||||
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
 | 
			
		||||
            android:hardwareAccelerated="true"
 | 
			
		||||
            android:launchMode="singleTop"
 | 
			
		||||
            android:theme="@style/LaunchTheme"
 | 
			
		||||
            android:windowSoftInputMode="adjustResize">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="android.intent.action.MAIN"/>
 | 
			
		||||
                <category android:name="android.intent.category.LAUNCHER"/>
 | 
			
		||||
                <action android:name="android.intent.action.MAIN" />
 | 
			
		||||
 | 
			
		||||
                <category android:name="android.intent.category.LAUNCHER" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </activity>
 | 
			
		||||
        <!-- Don't delete the meta-data below.
 | 
			
		||||
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
 | 
			
		||||
        <!--
 | 
			
		||||
 Don't delete the meta-data below.
 | 
			
		||||
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java
 | 
			
		||||
        -->
 | 
			
		||||
        <meta-data
 | 
			
		||||
            android:name="flutterEmbedding"
 | 
			
		||||
            android:value="2" />
 | 
			
		||||
    </application>
 | 
			
		||||
</manifest>
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
@ -0,0 +1,390 @@
 | 
			
		||||
package com.example.doctor_app_flutter;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
 | 
			
		||||
import android.Manifest;
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.res.ColorStateList;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.opengl.GLSurfaceView;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.CountDownTimer;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.MotionEvent;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.FrameLayout;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.RelativeLayout;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import com.opentok.android.Session;
 | 
			
		||||
import com.opentok.android.Stream;
 | 
			
		||||
import com.opentok.android.Publisher;
 | 
			
		||||
import com.opentok.android.PublisherKit;
 | 
			
		||||
import com.opentok.android.Subscriber;
 | 
			
		||||
import com.opentok.android.BaseVideoRenderer;
 | 
			
		||||
import com.opentok.android.OpentokError;
 | 
			
		||||
import com.opentok.android.SubscriberKit;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import pub.devrel.easypermissions.AfterPermissionGranted;
 | 
			
		||||
import pub.devrel.easypermissions.AppSettingsDialog;
 | 
			
		||||
import pub.devrel.easypermissions.EasyPermissions;
 | 
			
		||||
 | 
			
		||||
public class VideoCallActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks,
 | 
			
		||||
        Session.SessionListener,
 | 
			
		||||
        Publisher.PublisherListener,
 | 
			
		||||
        Subscriber.VideoListener {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = VideoCallActivity.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private static final int RC_SETTINGS_SCREEN_PERM = 123;
 | 
			
		||||
    private static final int RC_VIDEO_APP_PERM = 124;
 | 
			
		||||
 | 
			
		||||
    private Session mSession;
 | 
			
		||||
    private Publisher mPublisher;
 | 
			
		||||
    private Subscriber mSubscriber;
 | 
			
		||||
 | 
			
		||||
    private Handler mVolHandler;
 | 
			
		||||
    private Runnable mVolRunnable;
 | 
			
		||||
 | 
			
		||||
    private FrameLayout mPublisherViewContainer;
 | 
			
		||||
    private RelativeLayout mSubscriberViewContainer;
 | 
			
		||||
    private RelativeLayout controlPanel;
 | 
			
		||||
 | 
			
		||||
    private String  apiKey;
 | 
			
		||||
    private String  sessionId;
 | 
			
		||||
    private String  token;
 | 
			
		||||
    private String  callDuration;
 | 
			
		||||
    private String  warningDuration;
 | 
			
		||||
    private String  appLang;
 | 
			
		||||
 | 
			
		||||
    private boolean isSwitchCameraClicked;
 | 
			
		||||
    private boolean isCameraClicked;
 | 
			
		||||
    private boolean isSpeckerClicked;
 | 
			
		||||
    private boolean isMicClicked;
 | 
			
		||||
 | 
			
		||||
    private ImageView mCallBtn;
 | 
			
		||||
    private ImageView mCameraBtn;
 | 
			
		||||
    private ImageView mSwitchCameraBtn;
 | 
			
		||||
    private ImageView mspeckerBtn;
 | 
			
		||||
    private ImageView mMicBtn;
 | 
			
		||||
 | 
			
		||||
    private ProgressBar progressBar;
 | 
			
		||||
    private CountDownTimer countDownTimer;
 | 
			
		||||
    private TextView progressBarTextView;
 | 
			
		||||
    private RelativeLayout progressBarLayout;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        setTheme(R.style.AppTheme);
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_video_call);
 | 
			
		||||
        Objects.requireNonNull(getSupportActionBar()).hide();
 | 
			
		||||
        initUI();
 | 
			
		||||
        requestPermissions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onPause() {
 | 
			
		||||
        super.onPause();
 | 
			
		||||
 | 
			
		||||
        if (mSession == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        mSession.onPause();
 | 
			
		||||
 | 
			
		||||
        if (isFinishing()) {
 | 
			
		||||
            disconnectSession();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
 | 
			
		||||
        if (mSession == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        mSession.onResume();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onDestroy() {
 | 
			
		||||
        disconnectSession();
 | 
			
		||||
 | 
			
		||||
        super.onDestroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("ClickableViewAccessibility")
 | 
			
		||||
    private void initUI() {
 | 
			
		||||
        mPublisherViewContainer = (FrameLayout) findViewById(R.id.local_video_view_container);
 | 
			
		||||
        mSubscriberViewContainer = (RelativeLayout) findViewById(R.id.remote_video_view_container);
 | 
			
		||||
 | 
			
		||||
        apiKey = getIntent().getStringExtra("apiKey");
 | 
			
		||||
        sessionId = getIntent().getStringExtra("sessionId");
 | 
			
		||||
        token = getIntent().getStringExtra("token");
 | 
			
		||||
    //    callDuration = getIntent().getStringExtra("callDuration");
 | 
			
		||||
      //  warningDuration = getIntent().getStringExtra("warningDuration");
 | 
			
		||||
        appLang=getIntent().getStringExtra("appLang");
 | 
			
		||||
 | 
			
		||||
        controlPanel=findViewById(R.id.control_panel);
 | 
			
		||||
 | 
			
		||||
        mCallBtn = findViewById(R.id.btn_call);
 | 
			
		||||
        mCameraBtn = findViewById(R.id.btn_camera);
 | 
			
		||||
        mSwitchCameraBtn = findViewById(R.id.btn_switch_camera);
 | 
			
		||||
        mspeckerBtn = findViewById(R.id.btn_specker);
 | 
			
		||||
        mMicBtn = findViewById(R.id.btn_mic);
 | 
			
		||||
 | 
			
		||||
      //  progressBarLayout=findViewById(R.id.progressBar);
 | 
			
		||||
     //   progressBar=findViewById(R.id.progress_bar);
 | 
			
		||||
//        progressBarTextView=findViewById(R.id.progress_bar_text);
 | 
			
		||||
//        progressBar.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        hiddenButtons();
 | 
			
		||||
 | 
			
		||||
        mSubscriberViewContainer.setOnTouchListener((v, event) -> {
 | 
			
		||||
            controlPanel.setVisibility(View.VISIBLE);
 | 
			
		||||
            mVolHandler.removeCallbacks(mVolRunnable);
 | 
			
		||||
            mVolHandler.postDelayed(mVolRunnable, 5*1000);
 | 
			
		||||
            return true;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (appLang.equals("ar")) {
 | 
			
		||||
            progressBarLayout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private void hiddenButtons(){
 | 
			
		||||
        mVolHandler = new Handler();
 | 
			
		||||
        mVolRunnable = new Runnable() {
 | 
			
		||||
            public void run() {
 | 
			
		||||
                controlPanel.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        mVolHandler.postDelayed(mVolRunnable,5*1000);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
 | 
			
		||||
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
 | 
			
		||||
 | 
			
		||||
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onPermissionsGranted(int requestCode, List<String> perms) {
 | 
			
		||||
        Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onPermissionsDenied(int requestCode, List<String> perms) {
 | 
			
		||||
        Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size());
 | 
			
		||||
 | 
			
		||||
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
 | 
			
		||||
            new AppSettingsDialog.Builder(this)
 | 
			
		||||
                    .setTitle(getString(R.string.title_settings_dialog))
 | 
			
		||||
                    .setRationale(getString(R.string.rationale_ask_again))
 | 
			
		||||
                    .setPositiveButton(getString(R.string.setting))
 | 
			
		||||
                    .setNegativeButton(getString(R.string.cancel))
 | 
			
		||||
                    .setRequestCode(RC_SETTINGS_SCREEN_PERM)
 | 
			
		||||
                    .build()
 | 
			
		||||
                    .show();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @AfterPermissionGranted(RC_VIDEO_APP_PERM)
 | 
			
		||||
    private void requestPermissions() {
 | 
			
		||||
        String[] perms = {Manifest.permission.INTERNET, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
 | 
			
		||||
        if (EasyPermissions.hasPermissions(this, perms)) {
 | 
			
		||||
            mSession = new Session.Builder(VideoCallActivity.this, apiKey, sessionId).build();
 | 
			
		||||
            mSession.setSessionListener(this);
 | 
			
		||||
            mSession.connect(token);
 | 
			
		||||
        } else {
 | 
			
		||||
            EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, perms);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onConnected(Session session) {
 | 
			
		||||
        Log.i(TAG, "Session Connected");
 | 
			
		||||
 | 
			
		||||
        mPublisher = new Publisher.Builder(this).build();
 | 
			
		||||
        mPublisher.setPublisherListener(this);
 | 
			
		||||
 | 
			
		||||
        mPublisherViewContainer.addView(mPublisher.getView());
 | 
			
		||||
 | 
			
		||||
        if (mPublisher.getView() instanceof GLSurfaceView){
 | 
			
		||||
            ((GLSurfaceView) mPublisher.getView()).setZOrderOnTop(true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mSession.publish(mPublisher);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDisconnected(Session session) {
 | 
			
		||||
        Log.d(TAG, "onDisconnected: disconnected from session " + session.getSessionId());
 | 
			
		||||
 | 
			
		||||
        mSession = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onError(Session session, OpentokError opentokError) {
 | 
			
		||||
        Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in session " + session.getSessionId());
 | 
			
		||||
 | 
			
		||||
        Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show();
 | 
			
		||||
        finish();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onStreamReceived(Session session, Stream stream) {
 | 
			
		||||
        Log.d(TAG, "onStreamReceived: New stream " + stream.getStreamId() + " in session " + session.getSessionId());
 | 
			
		||||
 | 
			
		||||
        if (mSubscriber != null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        subscribeToStream(stream);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onStreamDropped(Session session, Stream stream) {
 | 
			
		||||
        Log.d(TAG, "onStreamDropped: Stream " + stream.getStreamId() + " dropped from session " + session.getSessionId());
 | 
			
		||||
 | 
			
		||||
        if (mSubscriber == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mSubscriber.getStream().equals(stream)) {
 | 
			
		||||
            mSubscriberViewContainer.removeView(mSubscriber.getView());
 | 
			
		||||
            mSubscriber.destroy();
 | 
			
		||||
            mSubscriber = null;
 | 
			
		||||
        }
 | 
			
		||||
        disconnectSession();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onStreamCreated(PublisherKit publisherKit, Stream stream) {
 | 
			
		||||
        Log.d(TAG, "onStreamCreated: Own stream " + stream.getStreamId() + " created");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onStreamDestroyed(PublisherKit publisherKit, Stream stream) {
 | 
			
		||||
        Log.d(TAG, "onStreamDestroyed: Own stream " + stream.getStreamId() + " destroyed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onError(PublisherKit publisherKit, OpentokError opentokError) {
 | 
			
		||||
        Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in publisher");
 | 
			
		||||
 | 
			
		||||
        Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show();
 | 
			
		||||
        finish();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onVideoDataReceived(SubscriberKit subscriberKit) {
 | 
			
		||||
        mSubscriber.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL);
 | 
			
		||||
        mSubscriberViewContainer.addView(mSubscriber.getView());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onVideoDisabled(SubscriberKit subscriberKit, String s) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onVideoEnabled(SubscriberKit subscriberKit, String s) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onVideoDisableWarning(SubscriberKit subscriberKit) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onVideoDisableWarningLifted(SubscriberKit subscriberKit) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void subscribeToStream(Stream stream) {
 | 
			
		||||
        mSubscriber = new Subscriber.Builder(VideoCallActivity.this, stream).build();
 | 
			
		||||
        mSubscriber.setVideoListener(this);
 | 
			
		||||
        mSession.subscribe(mSubscriber);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disconnectSession() {
 | 
			
		||||
        if (mSession == null) {
 | 
			
		||||
            finish();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mSubscriber != null) {
 | 
			
		||||
            mSubscriberViewContainer.removeView(mSubscriber.getView());
 | 
			
		||||
            mSession.unsubscribe(mSubscriber);
 | 
			
		||||
            mSubscriber.destroy();
 | 
			
		||||
            mSubscriber = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mPublisher != null) {
 | 
			
		||||
            mPublisherViewContainer.removeView(mPublisher.getView());
 | 
			
		||||
            mSession.unpublish(mPublisher);
 | 
			
		||||
            mPublisher.destroy();
 | 
			
		||||
            mPublisher = null;
 | 
			
		||||
        }
 | 
			
		||||
        mSession.disconnect();
 | 
			
		||||
        if(countDownTimer!=null) {
 | 
			
		||||
            countDownTimer.cancel();
 | 
			
		||||
        }
 | 
			
		||||
        finish();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onSwitchCameraClicked(View view) {
 | 
			
		||||
        if (mPublisher != null) {
 | 
			
		||||
            isSwitchCameraClicked = !isSwitchCameraClicked;
 | 
			
		||||
            mPublisher.cycleCamera();
 | 
			
		||||
            int res = isSwitchCameraClicked ? R.drawable.flip_disapled : R.drawable.flip_enabled;
 | 
			
		||||
            mSwitchCameraBtn.setImageResource(res);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onCameraClicked(View view) {
 | 
			
		||||
        if (mPublisher != null) {
 | 
			
		||||
            isCameraClicked = !isCameraClicked;
 | 
			
		||||
            mPublisher.setPublishVideo(!isCameraClicked);
 | 
			
		||||
            int res = isCameraClicked ? R.drawable.video_disanabled : R.drawable.video_enabled;
 | 
			
		||||
            mCameraBtn.setImageResource(res);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onSpeckerClicked(View view) {
 | 
			
		||||
        if (mSubscriber != null) {
 | 
			
		||||
            isSpeckerClicked = !isSpeckerClicked;
 | 
			
		||||
            mSubscriber.setSubscribeToAudio(!isSpeckerClicked);
 | 
			
		||||
            int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled;
 | 
			
		||||
            mspeckerBtn.setImageResource(res);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public void onMicClicked(View view) {
 | 
			
		||||
        if (mPublisher != null) {
 | 
			
		||||
            isMicClicked = !isMicClicked;
 | 
			
		||||
            mPublisher.setPublishAudio(!isMicClicked);
 | 
			
		||||
            int res = isMicClicked ? R.drawable.mic_disabled : R.drawable.mic_enabled;
 | 
			
		||||
            mMicBtn.setImageResource(res);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onCallClicked(View view) {
 | 
			
		||||
        disconnectSession();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,13 +1,45 @@
 | 
			
		||||
package com.example.doctor_app_flutter
 | 
			
		||||
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import io.flutter.embedding.android.FlutterActivity
 | 
			
		||||
import io.flutter.embedding.engine.FlutterEngine
 | 
			
		||||
import io.flutter.plugins.GeneratedPluginRegistrant
 | 
			
		||||
import io.flutter.embedding.android.FlutterFragmentActivity
 | 
			
		||||
import io.flutter.plugin.common.MethodChannel
 | 
			
		||||
 | 
			
		||||
class MainActivity: FlutterFragmentActivity() {
 | 
			
		||||
     override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
 | 
			
		||||
        GeneratedPluginRegistrant.registerWith(flutterEngine);
 | 
			
		||||
 | 
			
		||||
    private val CHANNEL = "Dr.cloudSolution/videoCall"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
 | 
			
		||||
        GeneratedPluginRegistrant.registerWith(flutterEngine)
 | 
			
		||||
 | 
			
		||||
         MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
 | 
			
		||||
             call, result ->
 | 
			
		||||
             if (call.method == "openVideoCall") {
 | 
			
		||||
                 val apiKey = call.argument<String>("kApiKey")
 | 
			
		||||
                 val sessionId = call.argument<String>("kSessionId")
 | 
			
		||||
                 val token = call.argument<String>("kToken")
 | 
			
		||||
              //   val callDuration = call.argument<String>("callDuration")
 | 
			
		||||
               //  val warningDuration = call.argument<String>("warningDuration")
 | 
			
		||||
                 val appLang = call.argument<String>("appLang")
 | 
			
		||||
                 openVideoCall(apiKey,sessionId,token/*,callDuration,warningDuration*/,appLang)
 | 
			
		||||
             } else {
 | 
			
		||||
                 result.notImplemented()
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?/*, callDuration: String?, warningDuration: String?*/, appLang: String?) {
 | 
			
		||||
        val intent = Intent(this, VideoCallActivity::class.java)
 | 
			
		||||
        intent.putExtra("apiKey", apiKey)
 | 
			
		||||
        intent.putExtra("sessionId", sessionId)
 | 
			
		||||
        intent.putExtra("token", token)
 | 
			
		||||
      //  intent.putExtra("callDuration", callDuration)
 | 
			
		||||
        //intent.putExtra("warningDuration", warningDuration)
 | 
			
		||||
        intent.putExtra("appLang", appLang)
 | 
			
		||||
        startActivity(intent)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
		 After Width: | Height: | Size: 5.9 KiB  | 
| 
		 After Width: | Height: | Size: 6.2 KiB  | 
| 
		 After Width: | Height: | Size: 13 KiB  | 
| 
		 After Width: | Height: | Size: 6.0 KiB  | 
| 
		 After Width: | Height: | Size: 6.6 KiB  | 
| 
		 After Width: | Height: | Size: 62 KiB  | 
| 
		 After Width: | Height: | Size: 5.6 KiB  | 
| 
		 After Width: | Height: | Size: 5.9 KiB  | 
| 
		 After Width: | Height: | Size: 5.0 KiB  | 
| 
		 After Width: | Height: | Size: 5.2 KiB  | 
| 
		 After Width: | Height: | Size: 2.7 KiB  | 
@ -0,0 +1,169 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:id="@+id/activity_clingo_video_call"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".VideoCallActivity">
 | 
			
		||||
    <RelativeLayout
 | 
			
		||||
        android:layout_width="fill_parent"
 | 
			
		||||
        android:layout_height="fill_parent"
 | 
			
		||||
        android:gravity="center_horizontal"
 | 
			
		||||
        android:keepScreenOn="true"
 | 
			
		||||
        android:clickable="true">
 | 
			
		||||
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:id="@+id/subscriberview"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_alignParentTop="true"
 | 
			
		||||
            android:layout_alignParentLeft="true"
 | 
			
		||||
            android:orientation="horizontal"/>
 | 
			
		||||
 | 
			
		||||
        <RelativeLayout
 | 
			
		||||
            android:id="@+id/publisherview"
 | 
			
		||||
            android:layout_height="200dp"
 | 
			
		||||
            android:layout_width="150dp"
 | 
			
		||||
            android:layout_alignParentBottom="true"
 | 
			
		||||
            android:layout_alignParentRight="true"
 | 
			
		||||
            android:paddingBottom="@dimen/activity_vertical_margin"
 | 
			
		||||
            android:paddingRight="@dimen/activity_horizontal_margin" />
 | 
			
		||||
    </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
    <RelativeLayout
 | 
			
		||||
        android:id="@+id/remote_video_view_container"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:background="@color/remoteBackground">
 | 
			
		||||
        <RelativeLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="match_parent"
 | 
			
		||||
            android:layout_above="@id/icon_padding">
 | 
			
		||||
 | 
			
		||||
            <ImageView
 | 
			
		||||
                android:layout_width="@dimen/remote_back_icon_size"
 | 
			
		||||
                android:layout_height="@dimen/remote_back_icon_size"
 | 
			
		||||
                android:layout_centerInParent="true"
 | 
			
		||||
                android:src="@drawable/video_off_fill" />
 | 
			
		||||
        </RelativeLayout>
 | 
			
		||||
        <RelativeLayout
 | 
			
		||||
            android:id="@+id/icon_padding"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="@dimen/remote_back_icon_margin_bottom"
 | 
			
		||||
            android:layout_alignParentBottom="true"/>
 | 
			
		||||
    </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
    <FrameLayout
 | 
			
		||||
        android:id="@+id/local_video_view_container"
 | 
			
		||||
        android:layout_width="@dimen/local_preview_width"
 | 
			
		||||
        android:layout_height="@dimen/local_preview_height"
 | 
			
		||||
        android:layout_alignParentEnd="true"
 | 
			
		||||
        android:layout_alignParentRight="true"
 | 
			
		||||
        android:layout_alignParentTop="true"
 | 
			
		||||
        android:layout_marginEnd="@dimen/local_preview_margin_right"
 | 
			
		||||
        android:layout_marginRight="@dimen/local_preview_margin_right"
 | 
			
		||||
        android:layout_marginTop="@dimen/local_preview_margin_top"
 | 
			
		||||
        android:background="@color/localBackground">
 | 
			
		||||
 | 
			
		||||
        <ImageView
 | 
			
		||||
            android:layout_width="@dimen/local_back_icon_size"
 | 
			
		||||
            android:layout_height="@dimen/local_back_icon_size"
 | 
			
		||||
            android:layout_gravity="center"
 | 
			
		||||
            android:scaleType="centerCrop"
 | 
			
		||||
            android:src="@drawable/video_off_fill" />
 | 
			
		||||
    </FrameLayout>
 | 
			
		||||
 | 
			
		||||
    <RelativeLayout
 | 
			
		||||
        android:id="@+id/control_panel"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_alignParentBottom="true"
 | 
			
		||||
        android:layout_marginBottom="60dp">
 | 
			
		||||
 | 
			
		||||
        <ImageView
 | 
			
		||||
            android:id="@+id/btn_call"
 | 
			
		||||
            android:layout_width="71dp"
 | 
			
		||||
            android:layout_height="71dp"
 | 
			
		||||
            android:layout_centerInParent="true"
 | 
			
		||||
            android:onClick="onCallClicked"
 | 
			
		||||
            android:scaleType="centerCrop"
 | 
			
		||||
            android:src="@drawable/call" />
 | 
			
		||||
 | 
			
		||||
        <ImageView
 | 
			
		||||
            android:id="@+id/btn_switch_camera"
 | 
			
		||||
            android:layout_width="39dp"
 | 
			
		||||
            android:layout_height="39dp"
 | 
			
		||||
            android:layout_centerVertical="true"
 | 
			
		||||
            android:layout_marginLeft="@dimen/control_bottom_horizontal_margin"
 | 
			
		||||
            android:layout_toEndOf="@id/btn_camera"
 | 
			
		||||
            android:layout_toRightOf="@id/btn_camera"
 | 
			
		||||
            android:onClick="onSwitchCameraClicked"
 | 
			
		||||
            android:scaleType="centerCrop"
 | 
			
		||||
            android:src="@drawable/flip_enabled" />
 | 
			
		||||
 | 
			
		||||
        <ImageView
 | 
			
		||||
            android:id="@+id/btn_camera"
 | 
			
		||||
            android:layout_width="39dp"
 | 
			
		||||
            android:layout_height="39dp"
 | 
			
		||||
            android:layout_centerVertical="true"
 | 
			
		||||
            android:layout_marginLeft="@dimen/control_bottom_horizontal_margin"
 | 
			
		||||
            android:layout_toEndOf="@id/btn_call"
 | 
			
		||||
            android:layout_toRightOf="@id/btn_call"
 | 
			
		||||
            android:onClick="onCameraClicked"
 | 
			
		||||
            android:scaleType="centerCrop"
 | 
			
		||||
            android:src="@drawable/video_enabled" />
 | 
			
		||||
 | 
			
		||||
        <ImageView
 | 
			
		||||
            android:id="@+id/btn_mic"
 | 
			
		||||
            android:layout_width="39dp"
 | 
			
		||||
            android:layout_height="39dp"
 | 
			
		||||
            android:layout_centerVertical="true"
 | 
			
		||||
            android:layout_marginRight="@dimen/control_bottom_horizontal_margin"
 | 
			
		||||
            android:layout_toStartOf="@id/btn_call"
 | 
			
		||||
            android:layout_toLeftOf="@id/btn_call"
 | 
			
		||||
            android:onClick="onMicClicked"
 | 
			
		||||
            android:scaleType="centerCrop"
 | 
			
		||||
            android:src="@drawable/mic_enabled" />
 | 
			
		||||
 | 
			
		||||
        <ImageView
 | 
			
		||||
            android:id="@+id/btn_specker"
 | 
			
		||||
            android:layout_width="39dp"
 | 
			
		||||
            android:layout_height="39dp"
 | 
			
		||||
            android:layout_centerVertical="true"
 | 
			
		||||
            android:layout_marginRight="@dimen/control_bottom_horizontal_margin"
 | 
			
		||||
            android:layout_toStartOf="@id/btn_mic"
 | 
			
		||||
            android:layout_toLeftOf="@id/btn_mic"
 | 
			
		||||
            android:onClick="onSpeckerClicked"
 | 
			
		||||
            android:scaleType="centerCrop"
 | 
			
		||||
            android:src="@drawable/audio_enabled" />
 | 
			
		||||
    </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
<!--    <RelativeLayout-->
 | 
			
		||||
<!--        android:id="@+id/progressBar"-->
 | 
			
		||||
<!--        android:layout_width="match_parent"-->
 | 
			
		||||
<!--        android:layout_height="40dp"-->
 | 
			
		||||
<!--        android:layout_alignParentBottom="true">-->
 | 
			
		||||
 | 
			
		||||
<!--        <ProgressBar-->
 | 
			
		||||
<!--            android:id="@+id/progress_bar"-->
 | 
			
		||||
<!--            android:layout_width="match_parent"-->
 | 
			
		||||
<!--            android:layout_height="31dp"-->
 | 
			
		||||
<!--            android:layout_alignParentEnd="true"-->
 | 
			
		||||
<!--            android:layout_alignParentBottom="true"-->
 | 
			
		||||
<!--            android:layout_marginEnd="0dp"-->
 | 
			
		||||
<!--            android:layout_marginBottom="0dp"-->
 | 
			
		||||
<!--            android:progressBackgroundTint="@color/colorProgressBarBackground"-->
 | 
			
		||||
<!--            style="@android:style/Widget.ProgressBar.Horizontal" />-->
 | 
			
		||||
 | 
			
		||||
<!--        <TextView-->
 | 
			
		||||
<!--            android:id="@+id/progress_bar_text"-->
 | 
			
		||||
<!--            android:layout_width="match_parent"-->
 | 
			
		||||
<!--            android:layout_height="wrap_content"-->
 | 
			
		||||
<!--            android:layout_marginLeft="9dp"-->
 | 
			
		||||
<!--            android:gravity="center_vertical"-->
 | 
			
		||||
<!--            android:textColor="@color/colorPrimary"-->
 | 
			
		||||
<!--            android:layout_centerInParent="true"/>-->
 | 
			
		||||
 | 
			
		||||
<!--    </RelativeLayout>-->
 | 
			
		||||
 | 
			
		||||
</RelativeLayout>
 | 
			
		||||
@ -0,0 +1,11 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <color name="colorPrimary">#ffffff</color>
 | 
			
		||||
    <color name="colorPrimaryDark">#303F9F</color>
 | 
			
		||||
    <color name="colorAccent">#fc3850</color>
 | 
			
		||||
    <color name="colorProgressBarBackground">#e4e9f2</color>
 | 
			
		||||
 | 
			
		||||
    <!-- Chat Activity -->
 | 
			
		||||
    <color name="localBackground">#827b92</color>
 | 
			
		||||
    <color name="remoteBackground">#484258</color>
 | 
			
		||||
</resources>
 | 
			
		||||
@ -0,0 +1,22 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <dimen name="activity_horizontal_margin">16dp</dimen>
 | 
			
		||||
    <dimen name="activity_vertical_margin">16dp</dimen>
 | 
			
		||||
    <dimen name="local_preview_margin_top">28dp</dimen>
 | 
			
		||||
    <dimen name="local_preview_margin_right">24dp</dimen>
 | 
			
		||||
 | 
			
		||||
    <!-- buttons -->
 | 
			
		||||
    <dimen name="call_button_size">60dp</dimen>
 | 
			
		||||
    <dimen name="other_button_size">54dp</dimen>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <dimen name="local_preview_width">88dp</dimen>
 | 
			
		||||
    <dimen name="local_preview_height">117dp</dimen>
 | 
			
		||||
    <dimen name="local_back_icon_size">50dp</dimen>
 | 
			
		||||
    <dimen name="remote_back_icon_size">100dp</dimen>
 | 
			
		||||
    <dimen name="remote_back_icon_margin_bottom">90dp</dimen>
 | 
			
		||||
 | 
			
		||||
    <!-- buttons -->
 | 
			
		||||
    <dimen name="control_bottom_margin">24dp</dimen>
 | 
			
		||||
    <dimen name="control_bottom_horizontal_margin">25dp</dimen>
 | 
			
		||||
</resources>
 | 
			
		||||
@ -0,0 +1,8 @@
 | 
			
		||||
<resources>
 | 
			
		||||
 | 
			
		||||
    <string name="remaining_en">Remaining Time In Seconds: </string>
 | 
			
		||||
    <string name="remaining_ar">الوقت المتبقي بالثانيه: </string>
 | 
			
		||||
    <string name="setting">Settings</string>
 | 
			
		||||
    <string name="cancel">Cancel</string>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
@ -0,0 +1,29 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/services.dart';
 | 
			
		||||
 | 
			
		||||
class VideoChannel{
 | 
			
		||||
  /// channel name
 | 
			
		||||
  static const _channel = const MethodChannel("Dr.cloudSolution/videoCall");
 | 
			
		||||
  static Future<dynamic> openVideoCallScreen(
 | 
			
		||||
      {kApiKey, kSessionId, kToken, callDuration, warningDuration}) {
 | 
			
		||||
    var result;
 | 
			
		||||
    try {
 | 
			
		||||
      result = _channel.invokeMethod(
 | 
			
		||||
        'openVideoCall',
 | 
			
		||||
        {
 | 
			
		||||
          "kApiKey": kApiKey,
 | 
			
		||||
          "kSessionId": kSessionId,
 | 
			
		||||
          "kToken": kToken,
 | 
			
		||||
       /*   "callDuration": callDuration,
 | 
			
		||||
          "warningDuration": warningDuration,*/
 | 
			
		||||
          "appLang": "en",
 | 
			
		||||
        },
 | 
			
		||||
      );
 | 
			
		||||
    } on PlatformException catch (e) {
 | 
			
		||||
      result = e.toString();
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||