当前位置:   article > 正文

调用系统录屏、截屏功能_pc 00000000001836d8 /system/lib64/libhwui.so

pc 00000000001836d8 /system/lib64/libhwui.so

安卓5.0及以上提供了支持截屏和录屏的API

布局如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:id="@+id/mainFrame"
  6. android:layout_height="match_parent">
  7. <Button android:layout_width="100dp"
  8. android:text="录屏"
  9. android:id="@+id/butview"
  10. android:layout_gravity="center"
  11. android:layout_height="60dp"/>
  12. <Button android:layout_width="100dp"
  13. android:text="截屏"
  14. android:layout_marginTop="100dp"
  15. android:id="@+id/capout"
  16. android:layout_gravity="center"
  17. android:layout_height="60dp"/>
  18. <ImageView
  19. android:id="@+id/img"
  20. android:layout_margin="60dp"
  21. android:layout_width="match_parent"
  22. android:layout_height="match_parent"/>
  23. </FrameLayout>

主代码如下:

  1. package com.example.leixiansheng.testactivity;
  2. import android.Manifest;
  3. import android.app.Activity;
  4. import android.content.ComponentName;
  5. import android.content.Intent;
  6. import android.content.ServiceConnection;
  7. import android.content.pm.PackageManager;
  8. import android.media.projection.MediaProjection;
  9. import android.media.projection.MediaProjectionManager;
  10. import android.os.IBinder;
  11. import android.support.v4.app.ActivityCompat;
  12. import android.support.v4.content.ContextCompat;
  13. import android.support.v7.app.AppCompatActivity;
  14. import android.os.Bundle;
  15. import android.util.DisplayMetrics;
  16. import android.view.View;
  17. import android.widget.Button;
  18. import android.widget.ImageView;
  19. import android.widget.Toast;
  20. public class MainActivity extends Activity {
  21. Button mButton, mCapButton;
  22. ImageView mImageView;
  23. private MediaProjectionManager projectionManager;
  24. private MediaProjection mediaProjection;
  25. private ScreenService recordService;
  26. private static int RECORD_REQUEST_CODE = 5;
  27. @Override
  28. protected void onCreate(Bundle savedInstanceState) {
  29. super.onCreate(savedInstanceState);
  30. setContentView(R.layout.activity_main);
  31. projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
  32. mButton = (Button) findViewById(R.id.butview);
  33. mCapButton = (Button) findViewById(R.id.capout);
  34. mImageView = (ImageView) findViewById(R.id.img);
  35. askPermission();
  36. Intent intent = new Intent(this, ScreenService.class);
  37. bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
  38. mButton.setOnClickListener(new View.OnClickListener() {
  39. @Override
  40. public void onClick(View view) {
  41. //######## 录屏逻辑 ########
  42. if (recordService.isRunning()) {
  43. recordService.stopRecord();
  44. mButton.setText("录屏");
  45. } else {
  46. //这里是请求录屏权限
  47. Intent captureIntent = projectionManager
  48. .createScreenCaptureIntent();
  49. startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
  50. }
  51. }
  52. });
  53. mCapButton.setOnClickListener(new View.OnClickListener() {
  54. @Override
  55. public void onClick(View view) {
  56. Intent in = new Intent(MainActivity.this, CapoutActivity.class);
  57. startActivity(in);
  58. }
  59. });
  60. }
  61. private void askPermission() {
  62. if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
  63. != PackageManager.PERMISSION_GRANTED) {
  64. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 102);
  65. }
  66. if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
  67. != PackageManager.PERMISSION_GRANTED) {
  68. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 103);
  69. }
  70. if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
  71. != PackageManager.PERMISSION_GRANTED) {
  72. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 104);
  73. }
  74. Intent intent = null;
  75. if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
  76. intent = projectionManager.createScreenCaptureIntent();
  77. startActivityForResult(intent, 101);//正常情况是要执行到这里的,作用是申请捕捉屏幕
  78. } else {
  79. Toast.makeText(this, "Android版本太低,无法使用该功能",Toast.LENGTH_SHORT).show();
  80. }
  81. }
  82. @Override
  83. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  84. if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
  85. //######## 录屏逻辑 ########
  86. mediaProjection = projectionManager
  87. .getMediaProjection(resultCode, data);
  88. recordService.setMediaProject(mediaProjection);
  89. recordService.startRecord();
  90. mButton.setText("结束");
  91. }
  92. }
  93. @Override
  94. protected void onDestroy() {
  95. super.onDestroy();
  96. unbindService(mServiceConnection);
  97. }
  98. /**
  99. * 绑定ScreenService
  100. */
  101. private ServiceConnection mServiceConnection = new ServiceConnection() {
  102. @Override
  103. public void onServiceConnected(ComponentName className, IBinder service) {
  104. DisplayMetrics metrics = new DisplayMetrics();
  105. getWindowManager().getDefaultDisplay().getMetrics(metrics);
  106. ScreenService.RecordBinder binder = (ScreenService.RecordBinder) service;
  107. recordService = binder.getRecordService();
  108. recordService
  109. .setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
  110. mButton.setEnabled(true);
  111. mButton.setText(recordService.isRunning() ? "结束" : "开始");
  112. }
  113. @Override
  114. public void onServiceDisconnected(ComponentName arg0) {}
  115. };
  116. }

ScreenService    记得Mainfest中注册

  1. package com.example.leixiansheng.testactivity;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.graphics.Bitmap;
  5. import android.graphics.PixelFormat;
  6. import android.hardware.display.DisplayManager;
  7. import android.hardware.display.VirtualDisplay;
  8. import android.media.Image;
  9. import android.media.ImageReader;
  10. import android.media.MediaRecorder;
  11. import android.media.projection.MediaProjection;
  12. import android.os.Binder;
  13. import android.os.Environment;
  14. import android.os.IBinder;
  15. import java.io.File;
  16. import java.io.IOException;
  17. import java.nio.ByteBuffer;
  18. /**
  19. * 项目名称:
  20. * 类描述: 录屏服务类
  21. */
  22. public class ScreenService extends Service {
  23. private MediaRecorder mediaRecorder;
  24. private VirtualDisplay virtualDisplay;
  25. private boolean running;
  26. private int width = 720;
  27. private int height = 1080;
  28. private int dpi;
  29. private ImageReader mImageReader;
  30. private MediaProjection mediaProjection;
  31. @Override
  32. public IBinder onBind(Intent intent) {
  33. return new RecordBinder();
  34. }
  35. @Override
  36. public void onCreate() {
  37. super.onCreate();
  38. running = false;
  39. mediaRecorder = new MediaRecorder();
  40. }
  41. @Override
  42. public int onStartCommand(Intent intent, int flags, int startId) {
  43. return super.onStartCommand(intent, flags, startId);
  44. }
  45. @Override
  46. public void onDestroy() {
  47. super.onDestroy();
  48. }
  49. public void setMediaProject(MediaProjection project) {
  50. mediaProjection = project;
  51. }
  52. public boolean isRunning() {
  53. return running;
  54. }
  55. public void setConfig(int width, int height, int dpi) {
  56. this.width = width;
  57. this.height = height;
  58. this.dpi = dpi;
  59. }
  60. /**
  61. * 开始录屏
  62. *
  63. * @return true
  64. */
  65. public boolean startRecord() {
  66. if (mediaProjection == null || running) {
  67. return false;
  68. }
  69. initRecorder();
  70. createVirtualDisplay();
  71. mediaRecorder.start();
  72. running = true;
  73. return true;
  74. }
  75. /**
  76. * 结束录屏
  77. *
  78. * @return true
  79. */
  80. public boolean stopRecord() {
  81. if (!running) {
  82. return false;
  83. }
  84. running = false;
  85. mediaRecorder.stop();
  86. mediaRecorder.reset();
  87. virtualDisplay.release();
  88. mediaProjection.stop();
  89. return true;
  90. }
  91. public void setMediaProjection(MediaProjection mediaProjection) {
  92. this.mediaProjection = mediaProjection;
  93. }
  94. /**
  95. * 初始化ImageRead参数
  96. */
  97. public void initImageReader() {
  98. if (mImageReader == null) {
  99. int maxImages = 2;
  100. mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, maxImages);
  101. createImageVirtualDisplay();
  102. }
  103. }
  104. /**
  105. * 创建一个录屏 Virtual
  106. */
  107. private void createVirtualDisplay() {
  108. virtualDisplay = mediaProjection
  109. .createVirtualDisplay("mediaprojection", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder
  110. .getSurface(), null, null);
  111. }
  112. /**
  113. * 创建一个ImageReader Virtual
  114. */
  115. private void createImageVirtualDisplay() {
  116. virtualDisplay = mediaProjection
  117. .createVirtualDisplay("mediaprojection", width, height, dpi,
  118. DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader
  119. .getSurface(), null, null);
  120. }
  121. /**
  122. * 初始化保存屏幕录像的参数
  123. */
  124. private void initRecorder() {
  125. mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  126. mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
  127. mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  128. mediaRecorder.setOutputFile(
  129. getSavePath() + System.currentTimeMillis() + ".mp4");
  130. mediaRecorder.setVideoSize(width, height);
  131. mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
  132. mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  133. mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
  134. mediaRecorder.setVideoFrameRate(30);
  135. try {
  136. mediaRecorder.prepare();
  137. } catch (IOException e) {
  138. e.printStackTrace();
  139. }
  140. }
  141. /**
  142. * 获取一个保存屏幕录像的路径
  143. *
  144. * @return path
  145. */
  146. public String getSavePath() {
  147. if (Environment.getExternalStorageState()
  148. .equals(Environment.MEDIA_MOUNTED)) {
  149. String rootDir = Environment.getExternalStorageDirectory()
  150. .getAbsolutePath() + "/" +
  151. "ScreenRecord" + "/";
  152. File file = new File(rootDir);
  153. if (!file.exists()) {
  154. if (!file.mkdirs()) {
  155. return null;
  156. }
  157. }
  158. return rootDir;
  159. } else {
  160. return null;
  161. }
  162. }
  163. /**
  164. * 请求完权限后马上获取有可能为null,可以通过判断is null来重复获取。
  165. */
  166. public Bitmap getBitmap() {
  167. Bitmap bitmap = cutoutFrame();
  168. if (bitmap == null) {
  169. getBitmap();
  170. }
  171. return bitmap;
  172. }
  173. /**
  174. * 通过底层来获取下一帧的图像
  175. *
  176. * @return bitmap
  177. */
  178. public Bitmap cutoutFrame() {
  179. Image image = mImageReader.acquireLatestImage();
  180. if (image == null) {
  181. return null;
  182. }
  183. int width = image.getWidth();
  184. int height = image.getHeight();
  185. final Image.Plane[] planes = image.getPlanes();
  186. final ByteBuffer buffer = planes[0].getBuffer();
  187. int pixelStride = planes[0].getPixelStride();
  188. int rowStride = planes[0].getRowStride();
  189. int rowPadding = rowStride - pixelStride * width;
  190. Bitmap bitmap = Bitmap.createBitmap(width +
  191. rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
  192. bitmap.copyPixelsFromBuffer(buffer);
  193. return Bitmap.createBitmap(bitmap, 0, 0, width, height);
  194. }
  195. public class RecordBinder extends Binder {
  196. public ScreenService getRecordService() {
  197. return ScreenService.this;
  198. }
  199. }
  200. }

CapoutActivity

  1. package com.example.leixiansheng.testactivity;
  2. import android.app.Activity;
  3. import android.content.ComponentName;
  4. import android.content.Intent;
  5. import android.content.ServiceConnection;
  6. import android.graphics.Bitmap;
  7. import android.media.projection.MediaProjection;
  8. import android.media.projection.MediaProjectionManager;
  9. import android.os.Bundle;
  10. import android.os.IBinder;
  11. import android.util.DisplayMetrics;
  12. import android.view.View;
  13. import android.widget.Button;
  14. import android.widget.ImageView;
  15. /**
  16. * 项目名称:
  17. * 类描述:截屏
  18. */
  19. public class CapoutActivity extends Activity {
  20. Button mButton;
  21. ImageView mImageView;
  22. private MediaProjectionManager projectionManager;
  23. private MediaProjection mediaProjection;
  24. private ScreenService recordService;
  25. private static int RECORD_REQUEST_CODE = 5;
  26. @Override
  27. protected void onCreate(Bundle savedInstanceState) {
  28. super.onCreate(savedInstanceState);
  29. setContentView(R.layout.activity_capout);
  30. projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
  31. mButton = (Button) findViewById(R.id.butview);
  32. mImageView = (ImageView) findViewById(R.id.img);
  33. Intent intent = new Intent(this, ScreenService.class);
  34. bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
  35. Intent captureIntent = projectionManager.createScreenCaptureIntent();
  36. startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
  37. mButton.setOnClickListener(new View.OnClickListener() {
  38. @Override
  39. public void onClick(View view) {
  40. //######## 截屏逻辑 ########
  41. Bitmap bitmap = recordService.getBitmap();
  42. mImageView.setImageBitmap(bitmap);
  43. }
  44. });
  45. }
  46. @Override
  47. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  48. if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
  49. //######## 截屏逻辑 ########
  50. mediaProjection = projectionManager.getMediaProjection(resultCode, data);
  51. recordService.setMediaProject(mediaProjection);
  52. recordService.initImageReader();
  53. }
  54. }
  55. @Override
  56. protected void onDestroy() {
  57. super.onDestroy();
  58. unbindService(mServiceConnection);
  59. }
  60. private ServiceConnection mServiceConnection = new ServiceConnection() {
  61. @Override
  62. public void onServiceConnected(ComponentName className, IBinder service) {
  63. DisplayMetrics metrics = new DisplayMetrics();
  64. getWindowManager().getDefaultDisplay().getMetrics(metrics);
  65. ScreenService.RecordBinder binder = (ScreenService.RecordBinder) service;
  66. recordService = binder.getRecordService();
  67. recordService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
  68. mButton.setEnabled(true);
  69. mButton.setText(recordService.isRunning() ? "结束" : "开始");
  70. }
  71. @Override
  72. public void onServiceDisconnected(ComponentName arg0) {}
  73. };
  74. }

参考与:android视频截屏&手机录屏实现_粗糙的汉子的博客-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/174893?site
推荐阅读
相关标签
  

闽ICP备14008679号