问题
I'm facing a problem where I can not find a solution right now.
I want to record the device screen.
When I click on the app icon, it should not open any apps, just a Notification
with a single "Start / Rec" button to start recording.
When clicking on this button, the device screen recording should start, the Notificatio
should still remain there.
In place of the "Start / Rec" button, a "Stop" button and the "message / title" of the notification the seconds that have passed since the moment in which the recording began.
The code to start recording and finish it I have already written, but there are some problems that I can not solve them here:
1) When I click on the app icon, only the notification should appear to decide whether to start recording or not.
So I do not have to use any setContentView
.
The problem is that when I click on the app icon, the Activity starts, even if it contains nothing setContentView
is like there was a patina, in fact there is the empty transparent activity of black color with opacity of 50% where you can see below the screen of the device with the icons below, but you can not make any gesture like clicking on other app or other things like that.
Only way is to exit the app in question, key back or close it.
For this problem what solution do you recommend? I had thought about managing it as an android widget, but I do not know.
2) As you know the actions of the NotificationCompat.Builder
, they work using Intent.
I have to make sure that: When I click on the "start" button, the recording starts. When I click on the "stop" button, it ends. So it must be the same registration to terminate, but working with the Intent, a new instance is started separately. How can I create a single instance to which I can refer and use their methods.
I had read something about using the services, but I'm not happy.
In short, I have to create a singleton for this thing.
Use onActivityResult
, to request permission to register I do something like this:
startActivityForResult(mProjectionManager.createScreenCaptureIntent (), CAST_PERMISSION_CODE);
Can you give me a hand?
package com.unkinstagram;
import android.content.Context;
import android.content.Intent;
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.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity2 extends AppCompatActivity {
private static final int CAST_PERMISSION_CODE = 22;
private DisplayMetrics mDisplayMetrics;
private MediaProjection mMediaProjection;
private VirtualDisplay mVirtualDisplay;
private MediaRecorder mMediaRecorder;
private MediaProjectionManager mProjectionManager;
private boolean startRec = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mDisplayMetrics = new DisplayMetrics();
mMediaRecorder = new MediaRecorder();
mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
Button start = (Button) findViewById(R.id.start);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (!startRec) {
prepareRecording("start");
startRecording();
}
}
});
Button stop = (Button) findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (startRec) stopRecording();
}
});
}
private void startRecording() {
startRec = true;
// If mMediaProjection is null that means we didn't get a context, lets ask the user
if (mMediaProjection == null) {
// This asks for user permissions to capture the screen
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), CAST_PERMISSION_CODE);
return;
}
mVirtualDisplay = getVirtualDisplay();
mMediaRecorder.start();
}
private void stopRecording() {
startRec = false;
if (mMediaRecorder != null) {
mMediaRecorder.stop();
mMediaRecorder.reset();
}
if (mVirtualDisplay != null) {
mVirtualDisplay.release();
}
if (mMediaProjection != null) {
mMediaProjection.stop();
}
}
public String getCurSysDate() {
return new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date());
}
private void prepareRecording(String name) {
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
Toast.makeText(this, "Failed to get External Storage", Toast.LENGTH_SHORT).show();
return;
}
final String directory = Environment.getExternalStorageDirectory() + File.separator + "Recordings";
final File folder = new File(directory);
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
if (!success) {
Toast.makeText(this, "Failed to create Recordings directory", Toast.LENGTH_SHORT).show();
return;
}
String videoName = (name + "_" + getCurSysDate() + ".mp4");
String filePath = directory + File.separator + videoName;
int width = mDisplayMetrics.widthPixels;
int height = mDisplayMetrics.heightPixels;
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncodingBitRate(8000 * 1000);
mMediaRecorder.setVideoFrameRate(24);
mMediaRecorder.setVideoSize(width, height);
mMediaRecorder.setOutputFile(filePath);
try {
mMediaRecorder.prepare();
} catch (Exception e) {
e.printStackTrace();
return;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != CAST_PERMISSION_CODE) {
// Where did we get this request from ? -_-
Log.w("class:", "Unknown request code: " + requestCode);
return;
}
if (resultCode != RESULT_OK) {
Toast.makeText(this, "Screen Cast Permission Denied :(", Toast.LENGTH_SHORT).show();
return;
}
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
// TODO Register a callback that will listen onStop and release & prepare the recorder for next recording
// mMediaProjection.registerCallback(callback, null);
mVirtualDisplay = getVirtualDisplay();
mMediaRecorder.start();
}
private VirtualDisplay getVirtualDisplay() {
int screenDensity = mDisplayMetrics.densityDpi;
int width = mDisplayMetrics.widthPixels;
int height = mDisplayMetrics.heightPixels;
return mMediaProjection.createVirtualDisplay(this.getClass().getSimpleName(),
width, height, screenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mMediaRecorder.getSurface(), null /*Callbacks*/, null /*Handler*/);
}
}
来源:https://stackoverflow.com/questions/54009658/creating-a-single-instance-through-a-singleton-of-a-main-activity-to-record-the