Sitemap

Build a Zoom clone with native android and WebRTC

5 min readMar 26, 2021

--

without wasting any time let’s start .

Open android studio and create a project .

Select empty activity and select name and all.

Select Java as programming language.

So the plan is to build splash screen , Profile for user , Login and Signup screens.

We will use Firebase for backend .

Let’s start with the splash screen .

xml of splash….

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/custom"
tools:context=".MainActivity">

<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="TODO"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.26"
tools:srcCompat="@tools:sample/avatars" />

<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="239dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>

In mainactivity.java file copy this..

package com.example.zoomclone;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {

startActivity(new Intent(MainActivity.this,SignupActivity.class));
}
},2000);
}
}

Now if you run this you will see a spinner in the splash screen.

Press enter or click to view image in full size

Next step is to handle sign in and sign up activities.

Before that let’s handle the firebase and firestore .

Head on to firebase.google.com and click on open console.

Add new project and navigate to authentication . Open docs and add dependencies in the project level gradle and app level gradle respectively.

Refer to ->

https://firebase.google.com/docs/android/setup

By right clicking on the package name (Java->package name) create an empty activity (new ->empty activity) and name it Signup activity .

Signup_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SignupActivity">

<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical">

<EditText
android:id="@+id/editTextTextPersonName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/buttonstyle"
android:ems="10"
android:hint="Enter username"
android:inputType="textPersonName"
android:padding="10dp" />

<EditText
android:id="@+id/emailBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/buttonstyle"
android:ems="10"
android:hint="Enter your email"
android:inputType="textEmailAddress"
android:padding="10dp" />

<EditText
android:id="@+id/PasswordBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/buttonstyle"
android:ems="10"
android:hint="Password"
android:inputType="textPassword"
android:padding="10dp" />

<Button
android:id="@+id/Create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/pressbutton"
android:text="Create Account"
android:textColor="#F1E7E7" />

<Button
android:id="@+id/Login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/pressbutton"
android:text="Already an user ? Login"
android:textColor="#FDFCFC" />

</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

SignupActivity.java

package com.example.zoomclone;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.FirebaseFirestore;

public class SignupActivity extends AppCompatActivity {
EditText emailbox,passwordbox,namebox;
Button loginbutton,signupbutton;
FirebaseAuth firebaseauth;
FirebaseFirestore database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup);
emailbox =findViewById(R.id.emailBox);
passwordbox=findViewById(R.id.PasswordBox);
loginbutton =findViewById(R.id.Login);
signupbutton = findViewById(R.id.Create);
namebox = findViewById(R.id.editTextTextPersonName);
firebaseauth = FirebaseAuth.getInstance();
database = FirebaseFirestore.getInstance();
final User user = new User();
user.setEmail(emailbox.getText().toString());
user.setUsername(namebox.getText().toString());
user.setPassword(passwordbox.getText().toString());

signupbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String email,password,usename;
email = emailbox.getText().toString();
password = passwordbox.getText().toString();
usename = namebox.getText().toString();
firebaseauth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
database.collection("Users").document().set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Toast.makeText(SignupActivity.this,"Account is created",Toast.LENGTH_SHORT).show();
startActivity(new Intent(SignupActivity.this,LoginActivity.class));
}
});

}else{
Toast.makeText(SignupActivity.this,task.getException().getLocalizedMessage(),Toast.LENGTH_LONG).show();
}
}
});


}
});
loginbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(SignupActivity.this,LoginActivity.class));
}
});
}
}
Press enter or click to view image in full size

In similar way create the Login activity.

In xml file of login activity add

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
tools:context=".LoginActivity">

<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical">

<EditText
android:id="@+id/emailBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/buttonstyle"
android:ems="10"
android:hint="Enter your email"
android:inputType="textEmailAddress"
android:padding="10dp" />

<EditText
android:id="@+id/PasswordBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/buttonstyle"
android:ems="10"
android:hint="Password"
android:inputType="textPassword"
android:padding="10dp" />

<Button
android:id="@+id/Login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/pressbutton"
android:text="Login"
android:textColor="#FDFCFC" />

<Button
android:id="@+id/Create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/pressbutton"
android:text="Create Account"
android:textColor="#F1E7E7" />

</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

In LoginActivity.java add

package com.example.zoomclone;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;

public class LoginActivity extends AppCompatActivity {
EditText email,password;
Button loginbutton,signupbutton;
FirebaseAuth firebase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
email =findViewById(R.id.emailBox);
password=findViewById(R.id.PasswordBox);
loginbutton =findViewById(R.id.Login);
signupbutton = findViewById(R.id.Create);
firebase=FirebaseAuth.getInstance();

loginbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String myemail,mypassword;
myemail = email.getText().toString();
mypassword=password.getText().toString();
firebase.signInWithEmailAndPassword(myemail,mypassword).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
Toast.makeText(LoginActivity.this,"Logged in",Toast.LENGTH_SHORT).show();
startActivity(new Intent(LoginActivity.this,ProfileActivity.class));
}else{
Toast.makeText(LoginActivity.this,task.getException().getLocalizedMessage(),Toast.LENGTH_SHORT).show();
}
}
});
}
});

signupbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(LoginActivity.this,SignupActivity.class));
}
});
}
}
Press enter or click to view image in full size

Now we need to add the user profile activity .

First create a new java class and add

package com.example.zoomclone;

public class User {
private String username;
private String email;
private String password;

public User(){

}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

This class is a blueprint for every user .

Set up Jitsi Sdk…

//Add this to project level gradlemaven {             url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases"         }
// Add this to app gradleimplementation ('org.jitsi.react:jitsi-meet-sdk:2.+') { transitive = true }Hit sync now

In profile activity’s xml file add

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProfileActivity">

<androidx.cardview.widget.CardView
android:layout_width="342dp"
android:layout_height="255dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:orientation="vertical"
android:padding="15dp">

<EditText
android:id="@+id/roomid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:ems="10"
android:hint="Room id"
android:inputType="textPersonName"
android:padding="10dp" />

<Button
android:id="@+id/joincall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="@drawable/pressbutton"
android:padding="10dp"
android:text="Join" />

<Button
android:id="@+id/sharebutton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/pressbutton"
android:text="Share" />

</LinearLayout>

</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

In ProfileActivity.Java add

package com.example.zoomclone;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import org.jitsi.meet.sdk.JitsiMeet;
import org.jitsi.meet.sdk.JitsiMeetActivity;
import org.jitsi.meet.sdk.JitsiMeetConferenceOptions;

import java.net.MalformedURLException;
import java.net.URL;

public class ProfileActivity extends AppCompatActivity {
EditText secretcodebox;
Button sharebutton,joinButton ;



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

secretcodebox = findViewById(R.id.roomid);
sharebutton = findViewById(R.id.sharebutton);
joinButton=findViewById(R.id.joincall);
URL serverUrl;
try{
serverUrl = new URL("https://meet.jit.si");
JitsiMeetConferenceOptions defaultoptions = new JitsiMeetConferenceOptions.Builder().setServerURL(serverUrl).setWelcomePageEnabled(false).build();
JitsiMeet.setDefaultConferenceOptions(defaultoptions);
} catch (MalformedURLException e) {
e.printStackTrace();
}



joinButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
JitsiMeetConferenceOptions options = new JitsiMeetConferenceOptions.Builder().setRoom(secretcodebox.getText().toString()).setWelcomePageEnabled(false).build();
JitsiMeetActivity.launch(ProfileActivity.this,options);
}
});

}
}
Press enter or click to view image in full size

Now your video calling app is ready .

Press enter or click to view image in full size
Jitsi chat window
Press enter or click to view image in full size

Reference ->

--

--