again.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="@+id/root_container"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/bg_circle"android:padding="10dp"><!-- Hide button at the top --><ImageViewandroid:id="@+id/hide_button"android:layout_width="42dp"android:layout_height="42dp"android:padding="3dp"android:src="@drawable/hide"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"tools:ignore="MissingConstraints" /><!-- imgCapture below hide_button --><ImageViewandroid:id="@+id/imgCapture"android:layout_width="@dimen/recording_icon_square"android:layout_height="@dimen/recording_icon_square"android:layout_below="@+id/hide_button"android:padding="3dp"android:src="@drawable/livefab"tools:ignore="MissingConstraints" /><!-- imgPause below imgCapture --><ImageViewandroid:id="@+id/imgPause"android:layout_width="@dimen/recording_icon_square"android:layout_height="@dimen/recording_icon_square"android:layout_below="@+id/imgCapture"android:padding="3dp"android:src="@drawable/screenshotfab"tools:ignore="MissingConstraints" /><!-- imgStart below imgPause --><ImageViewandroid:id="@+id/imgStart"android:layout_width="@dimen/recording_icon_square"android:layout_height="@dimen/recording_icon_square"android:layout_below="@+id/imgPause"android:padding="3dp"android:src="@drawable/startfab"tools:ignore="MissingConstraints" /><!-- imgStop below imgPause (hidden by default) --><ImageViewandroid:id="@+id/imgStop"android:layout_width="@dimen/recording_icon_square"android:layout_height="@dimen/recording_icon_square"android:layout_below="@+id/imgPause"android:padding="3dp"android:src="@drawable/stopfab"android:visibility="invisible"tools:ignore="MissingConstraints" /><!-- imgRec below imgStart --><ImageViewandroid:id="@+id/imgRec"android:layout_width="@dimen/recording_icon_square"android:layout_height="@dimen/recording_icon_square"android:layout_below="@+id/imgStart"android:src="@drawable/appicon" /><!-- imgLive below imgRec --><ImageViewandroid:id="@+id/imgLive"android:layout_width="@dimen/recording_icon_square"android:layout_height="@dimen/recording_icon_square"android:layout_below="@+id/imgRec"android:padding="3dp"android:src="@drawable/homefab"tools:ignore="MissingConstraints" /><!-- imgSetting below imgLive --><ImageViewandroid:id="@+id/imgSetting"android:layout_width="@dimen/recording_icon_square"android:layout_height="@dimen/recording_icon_square"android:layout_below="@+id/imgLive"android:padding="3dp"android:src="@drawable/settingsfab"tools:ignore="MissingConstraints" /><!-- imgClose below imgSetting --><ImageViewandroid:id="@+id/imgClose"android:layout_width="@dimen/recording_icon_square"android:layout_height="@dimen/recording_icon_square"android:layout_below="@id/imgSetting"android:padding="3dp"android:src="@drawable/cancelfab"tools:ignore="MissingConstraints" /></RelativeLayout>
RecordingControllerService .java
package com.virtoxed.screenrecorderlivestreamrecorder.services.recording;import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.media.MediaMetadataRetriever;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;import androidx.core.app.ActivityCompat;import com.virtoxed.screenrecorderlivestreamrecorder.R;
import com.virtoxed.screenrecorderlivestreamrecorder.controllers.settings.CameraSetting;
import com.virtoxed.screenrecorderlivestreamrecorder.controllers.settings.SettingManager;
import com.virtoxed.screenrecorderlivestreamrecorder.controllers.settings.VideoSetting;
import com.virtoxed.screenrecorderlivestreamrecorder.data.database.VideoDatabase;
import com.virtoxed.screenrecorderlivestreamrecorder.data.entities.Video;
import com.virtoxed.screenrecorderlivestreamrecorder.MainActivity;
import com.virtoxed.screenrecorderlivestreamrecorder.services.recording.RecordingService.RecordingBinder;
import com.virtoxed.screenrecorderlivestreamrecorder.utils.CameraPreview;
import com.virtoxed.screenrecorderlivestreamrecorder.utils.MyUtils;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Date;import static com.virtoxed.screenrecorderlivestreamrecorder.utils.MyUtils.DEBUG;public class RecordingControllerService extends Service {private static final String TAG = RecordingControllerService.class.getSimpleName();private RecordingService mRecordingService;private Boolean mRecordingServiceBound = false;private View mViewRoot;private View mCameraLayout;private WindowManager mWindowManager;WindowManager.LayoutParams paramViewRoot;WindowManager.LayoutParams paramCam;WindowManager.LayoutParams paramCountdown;private Intent mScreenCaptureIntent = null;private ImageView mImgClose, mImgRec, mImgStart, mImgStop, mImgPause, mImgCapture, mImgLive, mImgSetting,hideButton;private Boolean mRecordingStarted = false;private Boolean mRecordingPaused = false;private Camera mCamera;private LinearLayout cameraPreview;private CameraPreview mPreview;private int mScreenWidth, mScreenHeight;private View mViewCountdown;private TextView mTvCountdown;private View mCountdownLayout;private int mCameraWidth = 160, mCameraHeight = 90;@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {if(intent==null)return START_NOT_STICKY;String action = intent.getAction();if(action.equals(MyUtils.ACTION_UPDATE_SETTING)){handleUpdateSetting(intent);return START_NOT_STICKY;}if(DEBUG) Log.i(TAG, "RecordingControllerService: onStartCommand()");if(action != null){if(TextUtils.equals(action, "Camera_Available")){initCameraView();}}mScreenCaptureIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT);if(mScreenCaptureIntent == null){if(DEBUG) Log.i(TAG, "mScreenCaptureIntent is NULL");stopSelf();}else{if(DEBUG) Log.i(TAG, "RecordingControllerService: before run bindRecordingService()");bindRecordingService();}return super.onStartCommand(intent, flags, startId);}private void handleUpdateSetting(Intent intent) {int key = intent.getIntExtra(MyUtils.ACTION_UPDATE_SETTING, -1);switch (key){case R.string.setting_camera_size:updateCameraSize();break;case R.string.setting_camera_position:updateCameraPosition();break;case R.string.setting_camera_mode:updateCameraMode();break;}}private void updateCameraMode() {CameraSetting profile = SettingManager.getCameraProfile(getApplicationContext());if(profile.getMode().equals(CameraSetting.CAMERA_MODE_OFF))toggleView(mCameraLayout, View.GONE);else{if(mCameraLayout!=null){mWindowManager.removeViewImmediate(mCameraLayout);releaseCamera();initCameraView();}}}private void updateCameraPosition() {if(DEBUG) Log.i(TAG, "updateCameraPosition: ");CameraSetting profile = SettingManager.getCameraProfile(getApplicationContext());paramCam.gravity = profile.getParamGravity();paramCam.x = 0;paramCam.y = 0;mWindowManager.updateViewLayout(mCameraLayout,paramCam);}private void updateCameraSize() {CameraSetting profile = SettingManager.getCameraProfile(getApplicationContext());calculateCameraSize(profile);onConfigurationChanged(getResources().getConfiguration());}public RecordingControllerService() {}@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();if(DEBUG) Log.i(TAG, "RecordingControllerService: onCreate");updateScreenSize();initParam();initializeViews();}private void initParam() {int LAYOUT_FLAG;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;} else {LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;}paramViewRoot = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,LAYOUT_FLAG,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);paramCam = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,LAYOUT_FLAG,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);paramCountdown = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,LAYOUT_FLAG,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);}private void updateScreenSize() {DisplayMetrics metrics = getResources().getDisplayMetrics();mScreenWidth = metrics.widthPixels;mScreenHeight = metrics.heightPixels;}private void initCameraView() {if(DEBUG) Log.i(TAG, "RecordingControllerService: initializeCamera()");CameraSetting cameraProfile = SettingManager.getCameraProfile(getApplication());mCameraLayout = LayoutInflater.from(this).inflate(R.layout.layout_camera_view, null);if(cameraProfile.getMode().equals(CameraSetting.CAMERA_MODE_BACK))mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);elsemCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);cameraPreview = (LinearLayout) mCameraLayout.findViewById(R.id.camera_preview);calculateCameraSize(cameraProfile);onConfigurationChanged(getResources().getConfiguration());paramCam.gravity = cameraProfile.getParamGravity();paramCam.x = 0;paramCam.y = 0;mPreview = new CameraPreview(this, mCamera);cameraPreview.addView(mPreview);mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);mWindowManager.addView(mCameraLayout, paramCam);mCamera.startPreview();//re-inflate controllermWindowManager.removeViewImmediate(mViewRoot);mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);mWindowManager.addView(mViewRoot, paramViewRoot);if(cameraProfile.getMode().equals(CameraSetting.CAMERA_MODE_OFF))toggleView(cameraPreview, View.GONE);}private void calculateCameraSize(CameraSetting cameraProfile) {int factor;switch (cameraProfile.getSize()){case CameraSetting.SIZE_BIG:factor = 3;break;case CameraSetting.SIZE_MEDIUM:factor = 4;break;default: //smallfactor = 5;break;}if(mScreenWidth > mScreenHeight) {//landscapemCameraWidth = mScreenWidth / factor;mCameraHeight = mScreenHeight / factor;}else{mCameraWidth = mScreenHeight/factor;mCameraHeight = mScreenWidth/factor;}if(DEBUG) Log.i(TAG, "calculateCameraSize: "+mScreenWidth+"x"+mScreenHeight);}@Overridepublic void onConfigurationChanged(Configuration newConfig) {Log.d(TAG, "onConfigurationChanged: DETECTED" + newConfig.orientation);int width = mCameraWidth, height = mCameraHeight;ViewGroup.LayoutParams params = cameraPreview.getLayoutParams();if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){params.height = width;params.width = height;}else{params.height = height;params.width = width;}cameraPreview.setLayoutParams(params);}private void initializeViews() {if(DEBUG) Log.i(TAG, "RecordingControllerService: initializeViews()");mViewRoot = LayoutInflater.from(this).inflate(R.layout.layout_recording_again, null);mViewCountdown = LayoutInflater.from(this).inflate(R.layout.layout_countdown, null);paramViewRoot.gravity = Gravity.TOP | Gravity.START;paramViewRoot.x = 0;paramViewRoot.y = 100;mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);mWindowManager.addView(mViewCountdown, paramCountdown);mWindowManager.addView(mViewRoot, paramViewRoot);mCountdownLayout = mViewCountdown.findViewById(R.id.countdown_container);mTvCountdown = mViewCountdown.findViewById(R.id.tvCountDown);toggleView(mCountdownLayout, View.GONE);mImgRec = mViewRoot.findViewById(R.id.imgRec);mImgCapture = mViewRoot.findViewById(R.id.imgCapture);mImgClose = mViewRoot.findViewById(R.id.imgClose);mImgLive = mViewRoot.findViewById(R.id.imgLive);mImgPause = mViewRoot.findViewById(R.id.imgPause);mImgStart = mViewRoot.findViewById(R.id.imgStart);mImgSetting = mViewRoot.findViewById(R.id.imgSetting);mImgStop = mViewRoot.findViewById(R.id.imgStop);hideButton = mViewRoot.findViewById(R.id.hide_button);toggleView(mImgStop, View.GONE);toggleNavigationButton(View.GONE);hideButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 隐藏 layout_recording_again 布局mViewRoot.setVisibility(View.GONE);}});mImgCapture.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {MyUtils.toast(getApplicationContext(), "Capture clicked", Toast.LENGTH_SHORT);toggleNavigationButton(View.GONE);if(mCameraLayout.getVisibility() == View.GONE){toggleView(mCameraLayout, View.VISIBLE);}else{toggleView(mCameraLayout, View.GONE);}}});mImgPause.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {takeScreenshot();} catch (IOException e) {e.printStackTrace();}}});mImgSetting.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {MyUtils.toast(getApplicationContext(), "Setting clicked", Toast.LENGTH_SHORT);toggleNavigationButton(View.GONE);Intent intent = new Intent(getApplicationContext(), MainActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setAction(MyUtils.ACTION_OPEN_SETTING_ACTIVITY);startActivity(intent);}});mImgStart.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {toggleNavigationButton(View.GONE);if(mRecordingServiceBound){toggleView(mCountdownLayout, View.VISIBLE);int countdown = (SettingManager.getCountdown(getApplication())+1) * 1000;new CountDownTimer(countdown, 1000) {public void onTick(long millisUntilFinished) {toggleView(mViewRoot, View.GONE);mTvCountdown.setText(""+(millisUntilFinished / 1000));}public void onFinish() {toggleView(mCountdownLayout, View.GONE);toggleView(mViewRoot, View.VISIBLE);mRecordingStarted = true;mRecordingService.startRecording();MyUtils.toast(getApplicationContext(), "Recording Started", Toast.LENGTH_LONG);}}.start();}else{mRecordingStarted = false;MyUtils.toast(getApplicationContext(), "Recording Service connection has not been established", Toast.LENGTH_LONG);}}});mImgStop.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {toggleNavigationButton(View.GONE);if(mRecordingServiceBound){mRecordingStarted = false;final VideoSetting videoSetting = mRecordingService.stopRecording();if(videoSetting != null ){insertVideoToGallery(videoSetting);saveVideoToDatabase(videoSetting);}else{MyUtils.toast(getApplicationContext(), "Recording Service Closed", Toast.LENGTH_LONG);return;}}else{mRecordingStarted = true;MyUtils.toast(getApplicationContext(), "Recording Service connection has not been established", Toast.LENGTH_LONG);}}});mImgLive.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(getApplicationContext(), "Live clicked", Toast.LENGTH_SHORT).show();toggleNavigationButton(View.GONE);}});mImgClose.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mImgStop.performClick();stopSelf();}});mViewRoot.findViewById(R.id.root_container).setOnTouchListener(new View.OnTouchListener() {private int initialX;private int initialY;private float initialTouchX;private float initialTouchY;@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN://remember the initial position.initialX = paramViewRoot.x;initialY = paramViewRoot.y;//get the touch locationinitialTouchX = event.getRawX();initialTouchY = event.getRawY();return true;case MotionEvent.ACTION_UP:if(event.getRawX() < mScreenWidth/2) {paramViewRoot.x = 0;}else {paramViewRoot.x = mScreenWidth;}paramViewRoot.y = initialY + (int) (event.getRawY() - initialTouchY);//Update the layout with new X & Y coordinatemWindowManager.updateViewLayout(mViewRoot, paramViewRoot);int Xdiff = (int) (event.getRawX() - initialTouchX);int Ydiff = (int) (event.getRawY() - initialTouchY);//The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking.//So that is click event.if (Xdiff < 20 && Ydiff < 20) {if (isViewCollapsed()) {//When user clicks on the image view of the collapsed layout,//visibility of the collapsed layout will be changed to "View.GONE"//and expanded view will become visible.toggleNavigationButton(View.VISIBLE);}else {toggleNavigationButton(View.GONE);}}return true;case MotionEvent.ACTION_MOVE://Calculate the X and Y coordinates of the view.paramViewRoot.x = initialX + (int) (event.getRawX() - initialTouchX);paramViewRoot.y = initialY + (int) (event.getRawY() - initialTouchY);//Update the layout with new X & Y coordinatemWindowManager.updateViewLayout(mViewRoot, paramViewRoot);return true;}return false;}});mViewRoot.setOnFocusChangeListener(new View.OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {if(!hasFocus)toggleNavigationButton(View.GONE);}});}private void insertVideoToGallery(VideoSetting videoSetting) {Log.i(TAG, "insertVideoToGallery: ");//send video to galleryContentResolver cr = getContentResolver();ContentValues values = new ContentValues(2);values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");values.put(MediaStore.Video.Media.DATA, videoSetting.getOutputPath());// Add a new record (identified by uri) without the video, but with the values just set.Uri uri = cr.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);Log.i(TAG, "insertVideoToGallery: "+uri.getPath());sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));}private void saveVideoToDatabase(VideoSetting videoSetting) {String outputFile = videoSetting.getOutputPath();if(TextUtils.isEmpty(outputFile))return;MyUtils.toast(getApplicationContext(), "Recording Stopped"+outputFile, Toast.LENGTH_LONG);final Video mVideo = tryToExtractVideoFile(videoSetting);new Thread(new Runnable() {@Overridepublic void run() {if(mVideo !=null){if(DEBUG) Log.i(TAG, "onSaveVideo: "+mVideo.toString());synchronized (mVideo) {VideoDatabase.getInstance(getApplicationContext()).getVideoDao().insertVideo(mVideo);}Intent intent = new Intent(getApplicationContext(), MainActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setAction(MyUtils.ACTION_OPEN_VIDEO_MANAGER_ACTIVITY);startActivity(intent);}}}).start();}private Video tryToExtractVideoFile(VideoSetting videoSetting) {Video mVideo = null;try {File file = new File(Uri.parse(videoSetting.getOutputPath()).getPath());long size = file.length();String title = file.getName();int bitrate = videoSetting.getBitrate();int fps = videoSetting.getFPS();int width = videoSetting.getWidth();int height = videoSetting.getHeight();String localPath = videoSetting.getOutputPath();MediaMetadataRetriever mmr = new MediaMetadataRetriever();mmr.setDataSource(file.getAbsolutePath());long duration = Long.parseLong(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));mmr.release();mVideo = new Video(title, duration, bitrate, fps, width, height, size, localPath, "", "");if(DEBUG) Log.d(TAG, "tryToExtractVideoInfoFile: size: "+mVideo.toString());} catch (Exception e) {e.printStackTrace();Log.e(TAG, "tryToExtractVideoInfoFile: error-"+ e.getMessage());}return mVideo;}private void toggleView(View view, int visible) {view.setVisibility(visible);}private void bindRecordingService() {if(DEBUG) Log.i(TAG, "RecordingControllerService: bindRecordingService()");Intent mRecordingServiceIntent = new Intent(getApplicationContext(), RecordingService.class);mRecordingServiceIntent.putExtra(Intent.EXTRA_INTENT, mScreenCaptureIntent);bindService(mRecordingServiceIntent, mRecordingServiceConnection, Context.BIND_AUTO_CREATE);}private ServiceConnection mRecordingServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {RecordingBinder binder = (RecordingBinder) service;mRecordingService = binder.getService();mRecordingServiceBound = true;MyUtils.toast(getApplicationContext(), "Recording service connected", Toast.LENGTH_SHORT);}@Overridepublic void onServiceDisconnected(ComponentName name) {mRecordingServiceBound = false;MyUtils.toast(getApplicationContext(), "Recording service disconnected", Toast.LENGTH_SHORT);}};private boolean isViewCollapsed() {return mViewRoot == null || mViewRoot.findViewById(R.id.imgSetting).getVisibility() == View.GONE;}void toggleNavigationButton(int viewMode){//Todo: make animation heremImgStart.setVisibility(viewMode);mImgSetting.setVisibility(viewMode);mImgPause.setVisibility(viewMode);mImgCapture.setVisibility(viewMode);mImgLive.setVisibility(viewMode);mImgClose.setVisibility(viewMode);mImgStop.setVisibility(viewMode);if(viewMode == View.GONE){mViewRoot.setPadding(32,32, 32, 32);}else{if(mRecordingStarted){mImgStart.setVisibility(View.GONE);}else{mImgStop.setVisibility(View.GONE);}mViewRoot.setPadding(32,48, 32, 48);}}private void releaseCamera() {// stop and release cameraif (mCamera != null) {mCamera.stopPreview();mCamera.setPreviewCallback(null);mCamera.release();mCamera = null;}}@Overridepublic void onDestroy() {super.onDestroy();if(mViewRoot!=null){mWindowManager.removeViewImmediate(mViewRoot);}if(mCameraLayout!=null){mWindowManager.removeViewImmediate(mCameraLayout);releaseCamera();}if(mRecordingService!=null && mRecordingServiceBound) {unbindService(mRecordingServiceConnection);mRecordingServiceBound = false;}}private void takeScreenshot() throws IOException {Date now = new Date();android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);String fileName = now + ".jpg";try {File folder = new File(MyUtils.getBaseStorageDirectory(), MyUtils.createFileName(".jpg"));folder.mkdirs(); //create directory// create bitmap screen captureView v1 = mViewCountdown;v1.setDrawingCacheEnabled(true);Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());v1.setDrawingCacheEnabled(false);File imageFile = new File(folder, fileName);imageFile.createNewFile();FileOutputStream outputStream = new FileOutputStream(imageFile);int quality = 100;bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);outputStream.flush();outputStream.close();Toast.makeText(RecordingControllerService.this, "ScreenShot Captured", Toast.LENGTH_SHORT).show();MediaScannerConnection.scanFile(this,new String[]{imageFile.toString()}, null,new MediaScannerConnection.OnScanCompletedListener() {public void onScanCompleted(String path, Uri uri) {Log.i("ExternalStorage", "Scanned " + path + ":");Log.i("ExternalStorage", "-> uri=" + uri);}});} catch (Throwable e) {// Several error may come out with file handling or OOMe.printStackTrace();}}
}
代码参考github
com.virtoxed.screenrecorderlivestreamrecorder