当前位置: 首页 > news >正文

Android屏幕录制

这里使用Java语言编写实现,完整代码如下:

文件 AndroidMainfest.xml 的主要配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.demoapp"><!-- for 屏幕录制 --><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activityandroid:name=".ScreenRecordingActivity"android:exported="false"android:launchMode="singleTask"></activity><serviceandroid:name=".ScreenRecordingService"android:enabled="true"android:exported="true"android:foregroundServiceType="mediaProjection" /></application></manifest>

文件activity_screen_recording.xml的内容

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"tools:ignore="MissingConstraints"><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="center_horizontal"android:orientation="vertical"android:paddingTop="0dp"><!-- 注: SurfaceView不能设置background属性 --><!-- <SurfaceViewandroid:id="@+id/surface_view"android:layout_width="fill_parent"android:layout_height="80dp" /> --><TextViewandroid:id="@+id/textview_recording_info"android:layout_width="wrap_content"android:layout_height="100dp"android:layout_marginTop="20dp"android:layout_gravity="center"android:textColor="#333333"android:textSize="20sp"android:textStyle="bold"android:text="--"android:maxLines="5" /><Buttonandroid:id="@+id/btn_recording_start"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:text="开始录制" /><Buttonandroid:id="@+id/btn_recording_stop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:text="停止录制" /></LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>

文件ScreenRecordingActivity.java的完整代码

package com.example.demoapp;import android.Manifest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;import com.example.myandroidnfcapp.R;/*** @Function: 屏幕录制视频。* @Author: ChengJh。* @Date: 2023/09/06。* @Description: https://blog.csdn.net/qq_46546793/article/details/123279152 和 https://blog.csdn.net/weixin_42602900/article/details/128340037 。*/
public class ScreenRecordingActivity extends AppCompatActivity {private static final String TAG = ScreenRecordingActivity.class.getSimpleName();//录屏服务private ScreenRecordingService mService;private int mServiceStatus = ScreenRecordingService.statusInit;private boolean clickedStart = false;private ActivityResultLauncher activityLauncher;private TextView textViewInfo;private boolean prepared = false;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_screen_recording);ActionBar actionBar = getSupportActionBar();if (actionBar != null) {actionBar.setHomeButtonEnabled(true);actionBar.setDisplayHomeAsUpEnabled(true);actionBar.setTitle("录屏管理页面");}textViewInfo = findViewById(R.id.textview_recording_info);Button btnStart = (Button) findViewById(R.id.btn_recording_start);btnStart.setOnClickListener(view -> {startRecord();});Button btnStop = (Button) findViewById(R.id.btn_recording_stop);btnStop.setOnClickListener(view -> {stopRecord();});//注: registerForActivityResult()方法, 只能在onCreate()中注册, onStart()之后就不能注册了。。activityLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), o -> {System.out.println(TAG + "_registerForActivityResult_callback_" + o.getResultCode());if (o.getResultCode() == Activity.RESULT_OK) {actionAfterConfirmAgreed(o.getResultCode(), o.getData());}});}@Overridepublic void onStart() {super.onStart();}@Overridepublic void onResume() {super.onResume();/** 在Activity的六个核心回调 onCreate()、onStart()、onResume()、onPause()、onStop() 和 onDestroy() 中,*  onStart()、onResume()、onPause()、onStop() 会在 onRestart() 之后再次触发。*  因此, 有的任务如果放在其中某个函数内触发, 可能需要加个标记变量控制一下。*/if (!prepared) {prepared = true;checkPermission();}}@Overridepublic void onDestroy() {/** 页面销毁的时候, 可以不停止录屏 */// stopRecord();if (mServiceStatus >= ScreenRecordingService.statusServiceConnected) {unbindService(serviceConnection);}super.onDestroy();}// 标题栏返回按钮事件。@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case android.R.id.home://this.finish();this.onBackPressed();return true;}return super.onOptionsItemSelected(item);}// @Override// //返回方法, 获取返回的信息。// protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {//   super.onActivityResult(requestCode, resultCode, data);//   System.out.println(TAG + "_onActivityResult");//   //首先判断请求码是否一致, 结果是否ok 。//   if (requestCode == ScreenRecordingService.requestCode && resultCode == RESULT_OK) {//     actionAfterUserAgree(resultCode, data);//   }// }@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);System.out.println(TAG + "_onRequestPermissionsResult");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == ScreenRecordingService.requestCodeForPermisssion) {for (int i = 0; i < permissions.length; i++) {if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {return;}}connectService();}}/*** 权限申请*/private void checkPermission() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {String[] permissions = new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};for (String permission : permissions) {if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, permissions, ScreenRecordingService.requestCodeForPermisssion);return;}}}connectService();}//连接服务。public void connectService() {System.out.println(TAG + "_connectService");//通过intent为中介绑定Service, 会自动创建。Intent intent = new Intent(this, ScreenRecordingService.class);//绑定过程连接, 选择绑定模式。bindService(intent, serviceConnection, BIND_AUTO_CREATE);}//连接服务成功与否, 具体连接过程。//调用连接接口, 实现连接, 回调连接结果。private final ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {System.out.println(TAG + "_ServiceConnection_onServiceConnected");//服务连接成功, 需要通过Binder获取服务, 达到Activity和Service通信的目的ScreenRecordingService.ScreenRecordBinder binder = (ScreenRecordingService.ScreenRecordBinder) iBinder;//通过Binder获取ServicemService = binder.getScreenRecordService();mService.setListener(new ScreenRecordingService.ScreenRecordingServiceListener() {@Overridepublic void onPrepareComplete() {if (clickedStart && mService.startRecord()) {textViewInfo.setText("正在录屏");}}@Overridepublic void onRecordingFinish(String videoPath) {textViewInfo.setText("视频文件路径: " + videoPath);}});if (mService.isRunning()) {System.out.println(TAG + "_ServiceConnection_RunAlready");mServiceStatus = ScreenRecordingService.statusConfirmAgreed;textViewInfo.setText("正在录屏");if (clickedStart) {Toast.makeText(ScreenRecordingActivity.this, "已在录屏服务中", Toast.LENGTH_SHORT).show();}return;}mServiceStatus = ScreenRecordingService.statusServiceConnected;if (clickedStart) {actionAfterServiceConnected();}}@Overridepublic void onServiceDisconnected(ComponentName componentName) {//连接失败。Toast.makeText(ScreenRecordingActivity.this, "录屏服务未连接成功", Toast.LENGTH_SHORT).show();}};private void actionAfterConfirmAgreed(int resultCode, @Nullable Intent data) {mServiceStatus = ScreenRecordingService.statusConfirmAgreed;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {if (mService != null) {//获取录屏屏幕范围参数。DisplayMetrics metrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics);mService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);Intent intent = new Intent(this, ScreenRecordingService.class);intent.putExtra("code", resultCode);intent.putExtra("data", data);startForegroundService(intent);} else {System.out.println(TAG + "_onActivityResult_exception");}}}private void actionAfterServiceConnected() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//获取到服务, 初始化录屏管理者。MediaProjectionManager projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);//通过管理者, 创建录屏请求, 通过Intent。Intent captureIntent = projectionManager.createScreenCaptureIntent();//将请求码作为标识一起发送, 调用该接口, 需有返回方法。//startActivityForResult(captureIntent, ScreenRecordingService.requestCode);activityLauncher.launch(captureIntent);}}private void nextActionByStatus() {switch (mServiceStatus) {case ScreenRecordingService.statusInit://点击请求录屏时, 第一件事, 检查权限。checkPermission();break;case ScreenRecordingService.statusPermissionOK:connectService();break;case ScreenRecordingService.statusServiceConnected:actionAfterServiceConnected();break;default:if (mService != null) {if (mService.startRecord()) {textViewInfo.setText("正在录屏");}}break;}}private void startRecord() {System.out.println(TAG + "_startRecord_" + (null == mService));clickedStart = true;if (mService != null && mService.isRunning()) {//如果在录制, 弹出提示。Toast.makeText(ScreenRecordingActivity.this, "当前正在录屏, 请不要重复点击哦", Toast.LENGTH_SHORT).show();} else {//如果不在录制, 就开启录制。nextActionByStatus();}}private void stopRecord() {clickedStart = false;if (null == mService || !mService.isRunning()) {//没有录屏, 无需停止, 弹出提示。Toast.makeText(ScreenRecordingActivity.this, "还没有录屏, 无需停止", Toast.LENGTH_SHORT).show();} else {//停止录屏。mService.stopRecord();}}}

文件 ScreenRecordingService.java 的完整代码

package com.example.demoapp;import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
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.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;import androidx.annotation.Nullable;import com.example.myandroidnfcapp.MainActivity;
import com.example.myandroidnfcapp.R;import java.io.File;
import java.io.IOException;
import java.util.Objects;public class ScreenRecordingService extends Service {private static final String TAG = ScreenRecordingService.class.getSimpleName();public static final int statusInit = 0;public static final int statusPermissionOK = 1;public static final int statusServiceConnected = 2;public static final int statusConfirmAgreed = 3;public static final int requestCodeForPermisssion = 110;public static final int requestCode = 111;private MediaProjectionManager mediaProjectionManager;//录屏工具MediaProjection。private MediaProjection mediaProjection;//录像机MediaRecorder。private MediaRecorder mediaRecorder;//用于录屏的虚拟屏幕。private VirtualDisplay virtualDisplay;//录制屏幕的宽高像素。private int mWidth = 720;private int mHeight = 1280;private int mDpi = 1;//视频存储路径private String mVideoPath = "";//标志, 判断是否正在录屏private boolean running = false;//回调接口, 以及接口中要做的事。public interface ScreenRecordingServiceListener {void onPrepareComplete();void onRecordingFinish(String videoPath);}private ScreenRecordingServiceListener listener;@Overridepublic void onCreate() {super.onCreate();// HandlerThread serviceThread = new HandlerThread("service_thread", android.os.Process.THREAD_PRIORITY_BACKGROUND);// serviceThread.start();// running = false;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 注: mediaProjection的生成 必须在Service中进行。createNotificationChannel();int resultCode = intent.getIntExtra("code", -1);Intent resultData = intent.getParcelableExtra("data");Log.i(TAG, "onStartCommand_resultCode=" + resultCode);Log.i(TAG, "onStartCommand_resultData=" + resultData);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {if (null == mediaProjectionManager) {mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);}mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, Objects.requireNonNull(resultData));//mediaProjection = ((MediaProjectionManager) Objects.requireNonNull(getSystemService(Context.MEDIA_PROJECTION_SERVICE))).getMediaProjection(resultCode, resultData);Log.i(TAG, "mediaProjection_created");}if (listener != null) {listener.onPrepareComplete();}return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();}@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}//返回的Binder。public class ScreenRecordBinder extends Binder {//返回Service的方法。public ScreenRecordingService getScreenRecordService() {return ScreenRecordingService.this;}}@Nullable@Override//返回一个Binder用于通信, 需要一个获取Service的方法。public IBinder onBind(Intent intent) {return new ScreenRecordBinder();}//设置需要录制的屏幕参数。public void setConfig(int width, int height, int dpi) {mWidth = width;mHeight = height;mDpi = dpi;}public void setMediaProjectionManager(MediaProjectionManager projectionManager) {mediaProjectionManager = projectionManager;}public void setListener(ScreenRecordingServiceListener callback) {listener = callback;}//返回判断, 判断其是否在录屏。public boolean isRunning() {return running;}//服务的两个主要逻辑之一 ~ 开始录屏。public boolean startRecord() {Log.i(TAG, "startRecord");//首先判断是否有录屏工具以及是否在录屏if (null == mediaProjection || running) {return false;}//初始化录像机, 录音机Recorder。createRecorder();//根据获取的屏幕参数创建虚拟的录屏屏幕。createVirtualDisplay();//本来不加异常也可以, 但是这样就不知道是否start成功。//万一start没有成功, 但是running置为true了, 就产生了错误也无提示。//提示开始录屏了, 但是并没有工作。try {//准备工作都完成了, 可以开始录屏了。mediaRecorder.start();//标志位改为正在录屏。running = true;Toast.makeText(this, "录屏开启成功", Toast.LENGTH_SHORT).show();return true;} catch (Exception e) {e.printStackTrace();//有异常, start出错, 没有开始录屏。Toast.makeText(this, "录屏开启失败", Toast.LENGTH_SHORT).show();//标志位变回没有录屏的状态。running = false;return false;}}//服务的两个主要逻辑之一 ~ 停止录屏。public boolean stopRecord() {Log.i(TAG, "stopRecord");if (!running) {//没有在录屏, 无法停止。return false;}//无论设备是否还原或者有异常, 但是确实录屏结束, 修改标志位为未录屏。running = false;//本来加不加捕获异常都可以, 但是为了用户体验度, 添加会更好。try {//Recorder停止录像, 重置还原, 以便下一次使用。mediaRecorder.stop();mediaRecorder.reset();//释放virtualDisplay的资源。virtualDisplay.release();} catch (Exception e) {e.printStackTrace();//有异常, 保存失败。Toast.makeText(this, "录屏结束异常", Toast.LENGTH_SHORT).show();return false;}//无异常, 保存成功。Toast.makeText(this, "录屏结束 而且 保存成功", Toast.LENGTH_SHORT).show();if (listener != null) {listener.onRecordingFinish(mVideoPath);}return true;}//初始化Recorder录像机。public void createRecorder() {Log.i(TAG, "createRecorder");//创建Recorder。mediaRecorder = new MediaRecorder();//设置音频来源。mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置视频来源。mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);//设置视频格式为mp4。mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//设置视频存储地址。mVideoPath = getOutputFile().getAbsolutePath();//保存在该位置。mediaRecorder.setOutputFile(mVideoPath);//设置视频大小, 清晰度。mediaRecorder.setVideoSize(mWidth, mHeight);//设置视频编码为H264。mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置音频编码。mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置视频码率。mediaRecorder.setVideoEncodingBitRate(2 * mWidth * mHeight);mediaRecorder.setVideoFrameRate(16);//初始化完成, 进入准备阶段, 准备被使用。try {mediaRecorder.prepare();} catch (IOException e) {e.printStackTrace();//异常提示Toast.makeText(this, "Recorder录像机准备失败", Toast.LENGTH_SHORT).show();}}public void createVirtualDisplay() {//虚拟屏幕通过MediaProjection获取, 传入一系列传过来的参数。try {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {virtualDisplay = mediaProjection.createVirtualDisplay("VirtualScreen", mWidth, mHeight, mDpi,DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null);}} catch (Exception e) {e.printStackTrace();Toast.makeText(this, "virtualDisplay创建异常", Toast.LENGTH_SHORT).show();}}//获取输出存储文件夹的位置。public static File getOutputDirectory() {String directoryFilePathName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()+ "/ScreenRecording/";//创建该文件夹。File directoryFile = new File(directoryFilePathName);if (!directoryFile.exists()) {//如果该文件夹不存在。if (!directoryFile.mkdirs()) {//如果没有创建成功。return null;}}//创建成功了, 返回该目录。return directoryFile;}private File getOutputFile() {File directoryFile = getOutputDirectory();File file = new File(directoryFile, "SR" + System.currentTimeMillis() + ".mp4");// if (!file.exists()) {//   try {//     file.createNewFile();//   } catch (Exception e) {//     e.printStackTrace();//   }// }Log.i(TAG, "filePath_" + file.getAbsolutePath());return file;}private void createNotificationChannel() {Notification.Builder builder = new Notification.Builder(this.getApplicationContext()); //获取一个Notification构造器。Intent nIntent = new Intent(this, MainActivity.class); //点击后跳转的界面, 可以设置跳转数据。builder.setContentIntent(PendingIntent.getActivity(this, 0, nIntent, 0)).setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标)//.setContentTitle("ScreenRecording") // 设置下拉列表里的标题.setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标.setContentText("is running......") // 设置上下文内容.setWhen(System.currentTimeMillis()); // 设置该通知发生的时间/** 以下是对Android 8.0的适配 */if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {final String channelId = "MyChannelId";final String channelName = "MyChannelName";//普通notification适配。builder.setChannelId(channelId);//前台服务notification适配。NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW);notificationManager.createNotificationChannel(channel);}Notification notification = builder.build(); // 获取构建好的Notification对象。notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音。startForeground(requestCode, notification);}}

特别鸣谢下面链接:

(0)  https://blog.csdn.net/qq_46546793/article/details/123279152

(0)  https://blog.csdn.net/weixin_42602900/article/details/128340037

相关文章:

Android屏幕录制

这里使用Java语言编写实现&#xff0c;完整代码如下&#xff1a; 文件 AndroidMainfest.xml 的主要配置 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"package"…...

实在智能牵手埃林哲,“TARS-RPA-Agent+云时通”双剑合璧共推企业数字化转型

近日&#xff0c;《数字中国建设整体布局规划》进一步明确了数字化发展的方向和节奏&#xff0c;对企业数字化建设提出了新要求。回看过去几十年&#xff0c;信息化建设如火如荼&#xff0c;各类IT系统如雨后春笋般涌现&#xff0c;系统的自动化操作及系统间数据交互共享等需求…...

拥有这个中文版CustomGPT,你也能定制自己的AI问答机器人

人工智能技术的快速发展为各行各业带来了前所未有的机会&#xff0c;其中之一就是定制化的问答机器人。这些机器人可以用于客户支持、知识管理、虚拟助手等多个领域&#xff0c;帮助企业提高效率&#xff0c;提供更好的用户体验。很多人可能都知道通过CustomGPT能够设计自己的人…...

fastadmin 基本使用配置

fastadmin 版本 1.3.5 thinkphp 版本 5.0.25 配置 cache 为 redis 保存 // ---------------------------------------------------------------------- // | 缓存设置 // ---------------------------------------------------------------------- cache …...

netty 线程组

我们的bossgroup和workgroup都是使用的NioEventLoopGroup。其内部有一个EventExecutor类型的数组用来存储所有的线程组。 NioEventLoopGroup {EventExecutor[] children; }NioEventLoopGroup继承自MultithreadEventExecutorGroup&#xff0c;构造函数不指定线程数默认会根据系…...

Reactor 第十二篇 WebFlux集成PostgreSQL

1 引言 在现代的应用开发中&#xff0c;数据库是存储和管理数据的关键组件。PostgreSQL 是一种强大的开源关系型数据库&#xff0c;而 WebFlux 是 Spring 框架提供的响应式编程模型。本文将介绍如何使用 Reactor 和 WebFlux 集成 PostgreSQL&#xff0c;实现响应式的数据库访问…...

红队打靶:Me and My Girlfriend打靶思路详解(vulnhub)

目录 写在开头 第一步&#xff1a;主机发现和端口扫描 第二步&#xff1a;Web渗透&#xff08;修改XFF代理&#xff09; 第三步&#xff1a;数据库手工枚举 第四步&#xff1a;sudo php提权 总结与思考 写在开头 本篇博客在自己的理解之上根据大佬红队笔记的视频进行…...

Mysql高级——索引(2)

常见索引 索引分类 在MySQL数据库&#xff0c;将索引的具体类型主要分为以下几类&#xff1a;主键索引、唯一索引、常规索引、全文索引。 分类含义特点关键字主键索引针对于表中主键创建的索引默认自动创建, 只能有一个PRIMARY唯一索引避免同一个表中某数据列中的值重复可以…...

【史上最硬核分享】Docker+jenkinsPipeline 运行实现 python 自动化(超详细)

一、实现思路 在 Linux 服务器安装 docker创建 jenkins 容器jenkins 中创建 pipeline 项目根据自动化项目依赖包构建 python 镜像(构建自动化 python 环境)运行新的 python 容器&#xff0c;执行 jenkins 从仓库中拉下来的自动化项目执行完成之后删除容器 二、环境准备 Linu…...

leetcode 3. 无重复字符的最长子串

2023.9.15 本题我用的暴力双层for循环 unordered_set 解决的&#xff0c;外循环控制字符起始位置&#xff0c;内循环将字符放入 unordered_set&#xff0c;并查找有无重复的元素。 用了一个全局变量记录最长字串的长度&#xff0c;局部变量count记录当前层循环的最长子串长度…...

doccano 文本标注工具使用

最近在做面向大模型的文本标注工作&#xff0c;涉及到多人协同的问题&#xff0c;因此用到了doccano工具。 这个工具可以使用docker进行安装&#xff0c;安装之后的启动也都比较简单。 关于基础使用&#xff08;例如管理员登录、新建任务、上传数据集等&#xff09;&#xff…...

快速排序算法的递归和非递归

基本思路 选择一个基准值&#xff0c;将数组划分三个区域&#xff0c;小于基准值的区域位于左侧&#xff0c;等于基准值的区域位于中间&#xff0c;大于基准值的区域位于右侧。将大于和小于区域继续进行分区&#xff0c;周而复始&#xff0c;不断进行分区和交换&#xff0c;直…...

Maven无法拉取SNAPSHOT依赖的解决办法

背景 自己所在的部门主要是为其他项目组提供基础组件&#xff0c;如果需要使用新特性&#xff0c;其他项目组还会经常引用SNAPSHOT版本的组件进行开发测试。平时自己做测试的时候&#xff0c;因为手里有源码&#xff0c;所以每次都是先执行 mvn install 在本地安装后&#xff…...

day16-面向对象综合练习(上)

1. 设计游戏的目的 锻炼逻辑思维能力利用Java的图形化界面&#xff0c;写一个项目&#xff0c;知道前面学习的知识点在实际开发中的应用场景 2. 游戏的最终效果呈现 Hello&#xff0c;各位同学大家好。今天&#xff0c;我们要写一个非常有意思的小游戏 —《拼图小游戏》 我们…...

在Windos 10专业版搭建Fyne(Go 跨平台GUI)开发环境

目录 在Windos 10专业版搭建Fyne&#xff08;Go 跨平台GUI&#xff09;开发环境一 Fyne 和 MSYS2简介1.1 Fyne1.2 MSYS2 二 安装 MSYS22.1 下载MSYS22.2 安装2.3 环境变量设置2.4 检测安装环境 三 参考文档 在Windos 10专业版搭建Fyne&#xff08;Go 跨平台GUI&#xff09;开发…...

漫谈:C、C++字符串的困局

由于历史的原因&#xff0c;C、C字符串是个很让程序员头疼的东西。 字符串被解读为字符数组&#xff0c;但是又不等价于字符数组&#xff0c;而是带有附加的结束符的字符数组。 结束符‘\0’也是一个字符&#xff0c;但是又不计算在字符串长度里面&#xff08;strlen&#xff0…...

基于python+selenium的自动批量添加

场景 点击添加”新增“按钮&#xff0c;弹出”新增对话框“&#xff0c;输入各种数据&#xff0c;然后点击”确定“按钮&#xff0c;如此循环。数量多&#xff0c;这样操作累人。 selenium Selenium 是一个用于自动化 Web 浏览器操作的库&#xff0c;可以实现模拟点击、输入…...

gdb监视

怀疑踩内存了&#xff0c;如何利用gdb监视一段内存的值 在实际情况中&#xff0c;如果怀疑一个进程中的变量被踩内存了&#xff0c;但是不知道什么时候会被踩&#xff0c;就可以用下面的方法进行debug。GDB&#xff08;GNU Debugger&#xff09;是一个功能强大的调试工具&…...

STM32基础知识点总结

一、基础知识点 1、课程体系介绍 单片机概述arm体系结构STM32开发环境搭建 STM32-GPIO编程-点亮世界的那盏灯 STM32-USART串口应用SPI液晶屏 STM32-中断系统 STM32-时钟系统 STM32-ADC DMA 温湿度传感器-DHT11 2.如何学习单片机课程 多听理论、多理解、有问题及时提问 自己多…...

Python vs C#:首先学习哪种编程语言最好?

进入编码可能很困难。 最艰难的部分? 决定先学什么语言。 当谈到 Python 与 C# 时,可能很难知道在您的决定中要考虑哪些因素。 我们为您提供了有关这些全明星编程语言的所有信息。 什么是 C#? 自 2000 年作为 Microsoft Visual Studio 的一部分开发 C# 以来,它一直是开发人…...

代理IP和Socks5代理:跨界电商与全球爬虫的关键技术

跨界电商在全球化市场中崭露头角&#xff0c;而代理IP和Socks5代理则成为实现全球市场洞察和数据采集的不可或缺的工具。本文将深入探讨这两种代理技术在跨界电商、爬虫技术和出海战略中的关键作用。 引言&#xff1a; 介绍跨界电商的崛起和全球市场的机遇与挑战。引出代理IP…...

CentOS 7 调优之周期性的访问中断

文章目录 背景问题描述原因分析解决方案相关版本 背景 操作系统版本&#xff1a;CentOS Linux release 7.6.1810 (Core) 操作系统镜像安装后&#xff0c;未进行任何调整。正常部署应用&#xff0c;应用在 CentOS 7.9 未出现过此类现象。 问题描述 问题描述&#xff1a;负载教…...

SpringBoot表现层数据一致性

1.定义Restful类 说明&#xff1a;使用Data注解是Lombok库提供的一个注解&#xff0c;用于自动生成类的getter、setter、equals、hashcode和toString方法。 package com.forever.controller.utils;import lombok.Data;Data public class Restful {private Boolean flag;//dat…...

vue路由-两个树形结构数据-递归处理方法

1.vue静态路由 const dynamicRoutes [{path: /,name: /,component: () > import(//layout/index.vue),redirect: /home,meta: {isKeepAlive: true,},children: [{path: /home,name: home,component: () > import(//views/home/index.vue),meta: {title: 首页,isLink: ,…...

JSP SSM 成果展示系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 JSP SSM 冬奥建设成果展示系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的 源代码和数据库&#xff0c;系统主…...

脚本:python绘制七夕爱心

文章目录 效果脚本Reference 效果 脚本 import random from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGHT 640 # 画布的高 CANVAS_CENTER_X CANVAS_WIDTH / 2 # 画布中心的X轴坐标 CANVAS_CENTER_Y CANVAS_HEIGHT /…...

L1 项目概述与Hadoop部署

1.技术栈&#xff1a;HadoopHiveSqoopFlumeAzkaban Flume采集Nginx web服务器上的日志&#xff0c;采集完成后存储到Hadoop的平台&#xff0c;最终存储到HDFS上&#xff0c;处理和分析采用Hive的方式&#xff0c;处理完之后利用Sqoop导出到Mysql中&#xff0c;最终利用一个Java…...

关键词文章生成器-标题文章生成器

那就是如何在根据标题生成文章和根据关键词生成文章之间找到平衡之道。在这个信息时代&#xff0c;内容创作已经成为了一项重要的工作&#xff0c;无论是博客作者、社交媒体达人还是企业宣传&#xff0c;都需要不断地输出优质的内容。但是&#xff0c;我们常常陷入一个两难的困…...

深入了解MySQL中的JSON_ARRAYAGG和JSON_OBJECT函数

在MySQL数据库中&#xff0c;JSON格式的数据处理已经变得越来越常见。JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;它可以用来存储和表示结构化的数据。MySQL提供了一些功能强大的JSON函数&#xff0c;其中两个关键的函数是…...

Ubuntu22.04开启后屏幕黄屏

1. 故障现象 系统&#xff1a;Ubuntu22.04 现象&#xff1a;电脑从开机到进入桌面一直屏幕黄屏 2. 故障分析 可能为屏幕色彩调节出现故障 3. 解决方案 系统设置——》色彩——》删除原来的配置&#xff08;remove profile&#xff09;——》添加配置Colorspace:Compatibl…...

网站建设合同 域名/武汉关键词排名提升

首先来看看百度百科中是如何定义的&#xff1a; JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff1b;这种动态获取信息以及动态调用对象方法…...

网站优化北京哪家强?/网站怎样关键词排名优化

美国康宁公司 饶丹曙1 绿色和数据中心 在过去两年中&#xff0c;数据中心能耗问题被高度关注。美国环保署&#xff08;EPA&#xff09;公布了一项数据&#xff1a;2000~2006年&#xff0c;美国数据中心能耗增加了一倍&#xff0c;其中2006年电能消耗占全国的1.5%。换言之&…...

万网网站建设/如何在google上免费推广

主要的思路&#xff1a; 首先设置两个列表分别存放的是各种括号的开括号和闭括号&#xff0c;然后遍历给定的字符串&#xff0c;分如下几种情况&#xff1a; 1.字符串首字符出现在闭括号列表中&#xff0c;直接结束&#xff0c;输出错误 2.字符串长度不为偶数&#xff0c;直接结…...

wordpress长图拼接/镇江网页设计

一、 引言  异步JavaScript与XML(AJAX)是一个专用术语&#xff0c;用于实现在客户端脚本与服务器之间的数据交互过程。这一技术的优点在于&#xff0c;它向开发者提供了一种从Web服务器检索数据而不必把用户当前正在观察的页面回馈给服务器。与现代浏览器的通过存取浏览器DOM…...

做的网站为什么图片看不了怎么办/产品网络推广深圳

如何随机的取出数据表中的数据行&#xff1f;经过查找资料&#xff0c;有以下几种方式&#xff1a;利用oracle提供的dbms_randomselect * from (select a.proname,a.value,a.stat_date from wxxstat_test_temp a order by dbms_random.value) where rownum<5;也可以&#xf…...

互动模板wordpress/网站内容管理系统

文章目录多态综述多态的分类多态实现条件多态的实现形式多态的好处多态综述 class Shape {public void draw() {} } class Cycle extends Shape {Overridepublic void draw() {System.out.println("○");} } class Rect extends Shape {Overridepublic void draw() …...