Reputation: 127
I am trying a ScreenRecording application using media store API for Android 11.
My issue is, I am able to record screen recording below 2mins only. If the screen recording exceeds more than 2 mins, the file got created but it is in Kbs size only on clicking it says "Can't play this video" But if I record below 2 mins it works fine.
In Manifest, I am NOT using WRITE_EXTERNAL_STORAGE & requestLegacyExternalStorage permissions for Android 11, as per Google Guidelines
Pls, do help me if I missed any steps. Thanks in Advance!
I am Sharing by Code below,
INIT RECORDER:
private void recordScreen()
{
if(mediaProjection == null)
{
if(mediaProjectionManager!=null)
{
Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent();
startActivityForResult(permissionIntent, REQUEST_CODE);
}
return;
}
initRecorder();
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, android.content.Intent intent){
super.onActivityResult(requestCode, resultCode, intent);
destroyMediaProjection();
if(intent!=null)
{
createMediaProjection(resultCode, intent);
}
}
public void createMediaProjection(final int resultCode, final android.content.Intent data)
{
destroyMediaProjection();
mediaProjectionCallBack = new MediaProjectionCallBack();
long delay = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
foreGroundServiceIntent = new Intent(this, StartForegroundService.class);
System.out.println("calling ContextCompat.startForegroundService(this, intent)");
ContextCompat.startForegroundService(getApplicationContext(), foreGroundServiceIntent);
delay = 1000;
}
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Write whatever to want to do after delay specified (1 sec)
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
mediaProjection.registerCallback(mediaProjectionCallBack, null);
System.out.println("======createMediaProjection=========11111");
recordScreen();
}
}, delay);
}
private VirtualDisplay createVirtualDisplay()
{
return mediaProjection.createVirtualDisplay("Test", DISPLAY_WIDTH, DISPLAY_HEIGHT, mscreendenstity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(),null,null);
}
private class MediaProjectionCallBack extends MediaProjection.Callback
{
@Override
public void onStop()
{
System.out.println("MediaProjectionCallBack onStop() called");
stopRecordScreen();
super.onStop();
}
}
private void initRecorder()
{
if(mediaRecorder!=null)
{
mediaRecorder.release();
mediaRecorder = null;
}
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
String fileName = new StringBuilder("Recor_").append(new SimpleDateFormat("dd-mm-yyyy-hh_mm_ss").format(new java.util.Date())).append(".mp4").toString();
android.content.ContentValues values = new android.content.ContentValues(5);
values.put(MediaStore.Video.Media.DISPLAY_NAME, fileName);
values.put(MediaStore.Video.Media.TITLE, fileName);
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES + "/Test");
ContentResolver resolver = getBaseContext().getContentResolver();
Uri FinalvideoUri = resolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, FinalvideoUri));
File file = new File(FinalvideoUri.getPath());
videoUrl = getRealPathFromURI(this.getApplicationContext(),FinalvideoUri);
ParcelFileDescriptor file1 = this.getApplicationContext().getContentResolver().openFileDescriptor(FinalvideoUri,"w");
mediaRecorder.setOutputFile(file1.getFileDescriptor());
mediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setVideoEncodingBitRate(512 * 10000);
mediaRecorder.setVideoFrameRate(30);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int orientation = ORIENTATIONS.get(rotation + 90);
mediaRecorder.setOrientationHint(orientation);
mediaRecorder.prepare();
}
STOP RECORDING:
private void stopRecordScreen()
{
if(mediaRecorder!=null)
{
mediaRecorder.release();
mediaRecorder = null;
System.out.println("mediaRecorder released and assigned as null");
}
destroyMediaProjection();
stopTheForeGroundService();
if(virtualDisplay == null){
return;
}
virtualDisplay.release();
virtualDisplay = null;
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, videoUri));
}
private void destroyMediaProjection()
{
if(mediaProjection != null)
{
mediaProjection.unregisterCallback(mediaProjectionCallBack);
mediaProjection.stop();
mediaProjection = null;
System.out.println("mediaProjection stopped and assigned as null");
}
}
private Intent foreGroundServiceIntent;
private void stopTheForeGroundService()
{
final Handler handler = new Handler();
handler.postDelayed((new Runnable() {
@Override
public void run()
{
if(foreGroundServiceIntent!=null)
{
System.out.println("stopTheForeGroundService called");
stopService(foreGroundServiceIntent);
foreGroundServiceIntent = null;
if(StartForegroundService.instance!=null)
{
StartForegroundService.instance.stopForegroundService();
}
}
}
}), 1000);
}
Upvotes: 1
Views: 499
Reputation: 51
Hi Nijanthan I answered an improvement on MediaStore answer MediaStore.Images.Media.insertImage deprecated
I did use workManager and viewModel not sure if that would apply to your use-case, I did test my answer on API 26 and on API 30.
Upvotes: 1