安卓录屏软件添加隐藏按钮

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/487461.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

批量导出图片,按商品货号命名图片名-Excel易用宝

我们部门有这样一份商品信息表&#xff0c;包含着商品名称&#xff0c;货号和商品对应的图片&#xff0c;现在需要将这些商品图片导出&#xff0c;并且以对应的货号命名图片发给客户。 如果通过在图片上右键“另存为图片”&#xff0c;这样一张一张图片处理效率也太低了。 Exc…

关于SpringBoot项目创建后构建总是失败的问题

第一个问题&#xff1a;IDEA创建项目总是失败 原因&#xff1a;创建项目的时候默认使用的是https://start.spring.io&#xff0c;这个是一个外国网站&#xff0c;众所周知的就是国内访问总是出现不稳定的现象&#xff0c;这就是导致项目创建失败的最终原因。 解决方法&#x…

彻底理解布隆过滤器怎么解决缓存穿透问题

一.应用场景 实际业务中使用Redis&#xff0c;都是先通过用户插入数据到Mysql中&#xff0c;然后更新缓存到Redis&#xff0c;下一次用户再查询该数据的时候就可以通过Redis来进行查询。 先看下图&#xff0c;是假设的一个用户查询的场景&#xff1a; 首先用户查询的时候会去缓…

Leetcode数学部分笔记

Leetcode数学部分笔记 1. 回文数2. 加一3. 阶乘后的零4. x 的平方根5. Pow(x, n) 1. 回文数 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数 是指正序&#xff08;从左向右&#xff09;和倒序&…

大数据技术之新能源汽车数仓【附学习资源】

第一章 新能源汽车数仓的背景与意义 1.1 新能源汽车产业的爆发式增长 新能源汽车产业近年来呈现出爆发式增长&#xff0c;主要得益于全球范围内对环境保护和能源转型的高度重视。随着全球多个国家和地区对碳排放进行严格控制&#xff0c;政策层面的支持为新能源汽车的普及提供…

Nature:ChatGPT助力学术写作的方法

随着生成式AI技术的飞速发展&#xff0c;它在科研中的潜力也逐渐被探索和实践。在Nature最近的一篇文章里&#xff0c;Dritjon Gruda 副教授提到&#xff0c;生成式AI不仅在论文写作和编辑中扮演着越来越重要的角色&#xff0c;帮助科研人员提高工作效率&#xff0c;还在同行评…

分布式 分布式事务 总结

前言 相关系列 《分布式 & 目录》《分布式 & 分布式事务 & 总结》《分布式 & 分布式事务 & 问题》 分布式事务 所谓分布式事务是指操作范围笼罩多个不同节点的事务。例如对于订单节点&库存节点而言&#xff0c;一次完整的交易需要同时调动两个节…

UnityShaderLab 实现黑白着色器效果

实现思路&#xff1a;取屏幕像素的RGB值&#xff0c;将三个通道的值相加&#xff0c;除以一个大于值使颜色值在0-1内&#xff0c;再乘上一个强度值调节黑白强度。 在URP中实现需要开启Opaque Texture ShaderGraph实现&#xff1a; ShaderLab实现&#xff1a; Shader "Bl…

机器人的动力学前馈控制

机器人前馈技术可加快伺服驱动器内部的误差收敛速度&#xff0c;进而改善机器人的动态响应特性&#xff0c;解决机器人在运动过程中的抖动问题&#xff0c;提升机器人系统的精度和效率。 对于关节型机器人而言&#xff0c;在理想的刚性连接下&#xff0c;若给定每个关节所需要的…

Java基础——多线程基础

一、线程介绍 程序&#xff1a;是为完成特定任务&#xff0c;用某种语言编写的一组指令的集合。简单地说&#xff0c;就是我们写的代码进程&#xff1a; 进程是指运行中的程序&#xff0c;比如我们使用qq&#xff0c;就启动了一个进程。操作系统会为该进程分配内存空间。当我们…

在本地运行大语言模型

1&#xff0c;打开下面网站下载&#xff0c;软件 lm studio 2&#xff0c; 设置模型下载路径 3&#xff0c;没有魔法条件的人&#xff0c;去镜像网站下载模型的镜像文件 、 4&#xff0c;

JUC:Synchronized和锁升级

1. 面试题 谈谈你对Synchronized的理解Sychronized的锁升级你聊聊Synchronized实现原理&#xff0c;monitor对象什么时候生成的&#xff1f;知道monitor的monitorenter和monitorexit这两个是怎么保证同步的嘛&#xff1f;或者说这两个操作计算机底层是如何执行的偏向锁和轻量级…

网络知识:IP数据报知识详解

目录 一、IP数据报概念 二、IPV4数据报报头组成 三、IPV6数据报报头组成 今天给大家分享IP数据库相关的知识,希望对大家进一步了解IP协议提供一些帮助! 一、IP数据报概念 TCP/IP协议的网际层接收到传输层传递过来的数据单元,封装成向下(OSI模型的数据链路层、TCP/IP协…

消息中间件-Kafka2-3.9.0源码构建

消息中间件-Kafka2-3.9.0源码构建 1、软件环境 JDK Version 1.8Scala Version 2.12.0Kafka-3.9.0 源码包 下载地址&#xff1a;https://downloads.apache.org/kafka/3.9.0/kafka-3.9.0-src.tgzGradle Version > 8.8Apache Zookeeper 3.7.0 2、源码编译 打开源码根目录修改…

详解:HTTP/HTTPS协议

HTTP协议 一.HTTP是什么 HTTP&#xff0c;全称超文本传输协议&#xff0c;是一种用于分布式、协作式、超媒体信息系统的应用层协议。HTTP往往是基于传输层TCP协议实现的&#xff0c;采用的一问一答的模式&#xff0c;即发一个请求&#xff0c;返回一个响应。 Q&#xff1a;什…

vue中pdf.js的使用,包括pdf显示,跳转指定页面,高亮关键词

目录 一、下载pdf.js 二、引入到本地的项目中 三、实现预览pdf 四、跳转到指定页面 五、利用pdf里面的find查找关键词并可以监听updatefindcontrolstate统计个数 六、修改页面大小为实际大小 七、每次加载pdf都是在第一页 八、修改pdf滚动方式为横向 九、清除pdf缓存 十、pdf.j…

题海拾贝:力扣 231. 2 的幂

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《题海拾贝》、《数据结构与算法之美》 欢迎点赞&#xff0c;关注&#xff01; 目录 …

多级IIR滤波效果(BIQUAD),system verilog验证

MATLAB生成IIR系数 采用率1k&#xff0c;截止频率30hz&#xff0c;Matlab生成6阶对应的biquad3级系数 Verilog测试代码 // fs1khz,fc30hz initial beginreal Sig_Orig, Noise_white, Mix_sig;real fs 1000;Int T 1; //周期int N T*fs; //1s的采样点数// 数组声明…

【实战教程】使用YOLO和EasyOCR实现视频车牌检测与识别【附源码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

word poi-tl 图表功能增强,插入图表折线图、柱状图、饼状图

目录 问题解决问题poi-tl介绍 功能实现引入依赖功能介绍 功能实例饼图模版代码效果图 雷达图&#xff08;模版同饼图&#xff09;代码效果图 柱状图&#xff08;模版同饼图&#xff09;代码效果图 附加CustomCharts 工具类CustomChartSingleSeriesRenderData 数据对象CustomCha…