Screen Recorder in Android Studio



Today I'll teach you how to make a screen recording app in android studio.

Screen Recording feature is available only for API level above or equal 21(LOLLIPOP).
Before Lollipop app must require root permission to record screen.

You can also the whole project

Download Project


Follow the below instructions :-

1) Add the Storage permission and audio permission in your Android Manifest file.


<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
Your android manifest will look like below:-

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sanjay.ezyscreenrecorder">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>

</manifest>

2) Here I am using only one activity activity_main.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rootLayout"
android:background="#FFFFFF"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="@+id/btn_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/start_recording" />
</LinearLayout>
3) Then is our MainActivity.java. Here is our magic works....
package com.sanjay.ezyscreenrecorder;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.net.Uri;
import android.os.Bundle;

import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.View;
import android.widget.Button;

import android.widget.Toast;


import java.util.Timer;
import java.util.TimerTask;
import java.io.File;
import java.text.SimpleDateFormat;


import java.io.IOException;
import java.util.Calendar;

public class MainActivity extends AppCompatActivity {
private Timer timer = new Timer();
private TimerTask timerTask;


private static final String TAG = "MainActivity";
private String videofile= "";
private AlertDialog.Builder dialog;
private static final int REQUEST_CODE = 1000;
private int mScreenDensity;
Button btn_action;
private MediaProjectionManager mProjectionManager;
private static final int DISPLAY_WIDTH = 720;
private static final int DISPLAY_HEIGHT = 1280;
private MediaProjection mMediaProjection;
private VirtualDisplay mVirtualDisplay;
private MediaProjectionCallback mMediaProjectionCallback;
private MediaRecorder mMediaRecorder;
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
private static final int REQUEST_PERMISSION_KEY = 1;
boolean isRecording = false;
private Calendar calendar = Calendar.getInstance();


static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialog = new AlertDialog.Builder(this);





DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mScreenDensity = metrics.densityDpi;

mMediaRecorder = new MediaRecorder();

mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);





btn_action = (Button) findViewById(R.id.btn_action);
btn_action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

onToggleScreenShare();

}
});
}


public void actionBtnReload() {
if (isRecording) {
btn_action.setText(getString(R.string.stop_recording));
} else {
btn_action.setText(getString(R.string.start_recording));
}

}


public void onToggleScreenShare() {
if (!isRecording) {
String[] PERMISSIONS = {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO


};
if (!Function.hasPermissions(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_PERMISSION_KEY);
}else {
initRecorder();
shareScreen();
}
} else {
mMediaRecorder.stop();
mMediaRecorder.reset();
stopScreenSharing();
}
}

private void shareScreen() {
if (mMediaProjection == null) {
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
return;
}
mVirtualDisplay = createVirtualDisplay();
mMediaRecorder.start();
isRecording = true;
actionBtnReload();
}

private VirtualDisplay createVirtualDisplay() {
return mMediaProjection.createVirtualDisplay("MainActivity", DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null);
}

private void initRecorder() {
try {


File file = new File("/storage/emulated/0/Ezy/");
if(!file.exists()) {
file.mkdirs();
}
calendar=Calendar.getInstance();
videofile= "/storage/emulated/0/Ezy/Video".concat(new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss_a").format(calendar.getTime()).concat(".mp4"));
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); //THREE_GPP
mMediaRecorder.setOutputFile(videofile);
mMediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
mMediaRecorder.setVideoFrameRate(30); // 30
mMediaRecorder.setVideoEncodingBitRate(3000000);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int orientation = ORIENTATIONS.get(rotation + 90);
mMediaRecorder.setOrientationHint(orientation);
mMediaRecorder.prepare();



} catch (IOException e) {
e.printStackTrace();
}
}



private void stopScreenSharing() {
if (mVirtualDisplay == null) {
return;
}
mVirtualDisplay.release();
destroyMediaProjection();
isRecording = false;
actionBtnReload();
dialog.setTitle("Video is saved...");
dialog.setMessage("Saved in /storage/emulated/0/Ezy/");
dialog.setPositiveButton("View Video", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(videofile));
intent.setDataAndType(Uri.parse(videofile),
"video/*");
startActivity(intent);


}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

}
});
dialog.create().show();
}



private void destroyMediaProjection() {
if (mMediaProjection != null) {
mMediaProjection.unregisterCallback(mMediaProjectionCallback);
mMediaProjection.stop();
mMediaProjection = null;
}
Log.i(TAG, "MediaProjection Stopped");
}



@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != REQUEST_CODE) {
Log.e(TAG, "Unknown request code: " + requestCode);
return;
}
if (resultCode != RESULT_OK) {
Toast.makeText(this, "Screen Cast Permission Denied", Toast.LENGTH_SHORT).show();
isRecording = false;
actionBtnReload();
return;
}
mMediaProjectionCallback = new MediaProjectionCallback();
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
btn_action.setEnabled(false);
moveTaskToBack(true);

timerTask = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Screen Recording is started", Toast.LENGTH_SHORT).show();
timerTask = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
btn_action.setEnabled(true);
mMediaProjection.registerCallback(mMediaProjectionCallback, null);
mVirtualDisplay = createVirtualDisplay();
isRecording = true;
actionBtnReload();



mMediaRecorder.start();


}
});
}
};
timer.schedule(timerTask, (int)(500));
}
});
}
};
timer.schedule(timerTask,(int)(500));

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_PERMISSION_KEY:
{
if ((grantResults.length > 0) && (grantResults[0] + grantResults[1]) == PackageManager.PERMISSION_GRANTED) {
onToggleScreenShare();
} else {
isRecording = false;
actionBtnReload();
Snackbar.make(findViewById(android.R.id.content), "Please enable Microphone and Storage permissions.",
Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:" + getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(intent);
}
}).show();
}
return;
}
}
}





private class MediaProjectionCallback extends MediaProjection.Callback {
@Override
public void onStop() {
if (isRecording) {
isRecording = false;
actionBtnReload();
mMediaRecorder.stop();
mMediaRecorder.reset();
}
mMediaProjection = null;
stopScreenSharing();
}
}



@Override
public void onDestroy() {
super.onDestroy();
destroyMediaProjection();
}

@Override
public void onBackPressed() {
if (isRecording) {
Snackbar.make(findViewById(android.R.id.content), "Wanna Stop recording and exit?",
Snackbar.LENGTH_INDEFINITE).setAction("Stop",
new View.OnClickListener() {
@Override
public void onClick(View v) {
mMediaRecorder.stop();
mMediaRecorder.reset();
Log.v(TAG, "Stopping Recording");
stopScreenSharing();
finish();
}
}).show();
} else {
finish();
}
}
}

Here I am using Ezy folder to save Videos...



4)Then I am using another java class to request permission.


package com.sanjay.ezyscreenrecorder;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;



public class Function {

public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}


}
5) Here is my string.xml file:-

<resources>
<string name="app_name">Ezy Screen Recorder</string>
<string name="stop_recording">Stop Recording</string>
<string name="start_recording">Start Recording</string>
</resources>



Now Build and Sync project and make an apk file, then test it on your device...

Thank you...


Comments

Popular posts from this blog

How to zip files in Sketchware

Make a layout with rounded corners in sketchware