android实现录屏功能

本文实例为大家分享了android实现录屏功能的具体代码,供大家参考,具体内容如下

1、mian.activity

package com.fpt.screenvideo;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.projection.MediaProjectionManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RadioGroup;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

 private static final String TAG = "MainActivity";

 private Button mTextView,off_btn;

 private static final String RECORD_STATUS = "record_status";
 private static final int REQUEST_CODE = 1000;

 private int mScreenWidth;
 private int mScreenHeight;
 private int mScreenDensity;

 /** 是否已经开启视频录制 */
 private boolean isStarted = false;
 /** 是否为标清视频 */
 private boolean isVideoSd = true;
 /** 是否开启音频录制 */
 private boolean isAudio = true;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  Log.i(TAG, "onCreate");
  if(savedInstanceState != null) {
   isStarted = savedInstanceState.getBoolean(RECORD_STATUS);
  }
  getView() ;
  getScreenBaseInfo();
 }
 private void getView() {
  mTextView = findViewById(R.id.button_control);
  off_btn=findViewById(R.id.button_contro2);
  off_btn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
////    Intent service = new Intent(this, ScreenRecordService.class);
//    stopService(service);
//    isStarted = !isStarted;
   }
  });
  if(isStarted) {
   statusIsStarted();
  } else {
   statusIsStoped();
  }
  mTextView.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    if(isStarted) {

     stopScreenRecording();//功能
     statusIsStoped();//仅仅是状态
     Log.i(TAG, "Stoped screen recording");
    } else {
     startScreenRecording();//功能
    }
   }
  });

  RadioGroup radioGroup = (RadioGroup) findViewById(R.id.redio_group);
  radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

   @Override
   public void onCheckedChanged(RadioGroup group, int checkedId) {
    // TODO Auto-generated method stub
    switch (checkedId) {
     case R.id.sd_button:
      isVideoSd = true;
      break;
     case R.id.hd_button:
      isVideoSd = false;
      break;

     default:
      break;
    }
   }
  });

  CheckBox audioBox = (CheckBox) findViewById(R.id.audio_check_box);
  audioBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

   @Override
   public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    // TODO Auto-generated method stub
    isAudio = isChecked;
   }
  });
 }

 /**
  * 开启屏幕录制时的UI状态
  */
 private void statusIsStarted() {
  mTextView.setText("停止录制");
  mTextView.setBackgroundColor(Color.GREEN);
 }

 /**
  * 结束屏幕录制后的UI状态
  */
 private void statusIsStoped() {
  mTextView.setText("开始录制");
  mTextView.setBackgroundColor(Color.RED);
 }

 /**
  * 获取屏幕相关数据
  */
 private void getScreenBaseInfo() {
  DisplayMetrics metrics = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(metrics);
  mScreenWidth = metrics.widthPixels;
  mScreenHeight = metrics.heightPixels;
  mScreenDensity = metrics.densityDpi;
 }

 @Override
 protected void onSaveInstanceState(Bundle outState) {
  // TODO Auto-generated method stub
  super.onSaveInstanceState(outState);
  outState.putBoolean(RECORD_STATUS, isStarted);
 }

 /**
  * 获取屏幕录制的权限
  */
 private void startScreenRecording() {
  // TODO Auto-generated method stub
  MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
  Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent();
  startActivityForResult(permissionIntent, REQUEST_CODE);
 }

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  // TODO Auto-generated method stub
  super.onActivityResult(requestCode, resultCode, data);
  if(requestCode == REQUEST_CODE) {
   if(resultCode == RESULT_OK) {
    // 获得权限,启动Service开始录制
    Intent service = new Intent(this, ScreenRecordService.class);
    service.putExtra("code", resultCode);
    service.putExtra("data", data);
    service.putExtra("audio", isAudio);
    service.putExtra("width", mScreenWidth);
    service.putExtra("height", mScreenHeight);
    service.putExtra("density", mScreenDensity);
    service.putExtra("quality", isVideoSd);
    startService(service);
    // 已经开始屏幕录制,修改UI状态
    isStarted = !isStarted;
    statusIsStarted();
//    simulateHome(); // this.finish(); // 可以直接关闭Activity
    Log.i(TAG, "Started screen recording");
   } else {
    Toast.makeText(this, "跳出提示框", Toast.LENGTH_LONG).show();
    Log.i(TAG, "User cancelled");
   }
  }
 }

 /**
  * 关闭屏幕录制,即停止录制Service
  */
 private void stopScreenRecording() {
  // TODO Auto-generated method stub
  Intent service = new Intent(this, ScreenRecordService.class);
  stopService(service);
  isStarted = !isStarted;
 }

 /**
  * 模拟HOME键返回桌面的功能
  */
 private void simulateHome() {
  Intent intent = new Intent(Intent.ACTION_MAIN);
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  intent.addCategory(Intent.CATEGORY_HOME);
  this.startActivity(intent);
 }

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  // 在这里将BACK键模拟了HOME键的返回桌面功能(并无必要)
  if(keyCode == KeyEvent.KEYCODE_BACK) {
   simulateHome();
   return true;
  }
  return super.onKeyDown(keyCode, event);
 }

}

2、ScreenRecordService

package com.fpt.screenvideo;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ScreenRecordService extends Service {
 private static final String TAG = "ScreenRecordingService";

 private int mScreenWidth;
 private int mScreenHeight;
 private int mScreenDensity;
 private int mResultCode;
 private Intent mResultData;
 /** 是否为标清视频 */
 private boolean isVideoSd;
 /** 是否开启音频录制 */
 private boolean isAudio;

 private MediaProjection mMediaProjection;
 private MediaRecorder mMediaRecorder;
 private VirtualDisplay mVirtualDisplay;

 @Override
 public void onCreate() {
  // TODO Auto-generated method stub
  super.onCreate();
  Log.i(TAG, "Service onCreate() is called");
 }

 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
  // TODO Auto-generated method stub
  Log.i(TAG, "Service onStartCommand() is called");

  mResultCode = intent.getIntExtra("code", -1);
  mResultData = intent.getParcelableExtra("data");
  mScreenWidth = intent.getIntExtra("width", 720);
  mScreenHeight = intent.getIntExtra("height", 1280);
  mScreenDensity = intent.getIntExtra("density", 1);
  isVideoSd = intent.getBooleanExtra("quality", true);
  isAudio = intent.getBooleanExtra("audio", true);

  mMediaProjection = createMediaProjection();
  mMediaRecorder = createMediaRecorder();
  mVirtualDisplay = createVirtualDisplay(); // 必须在mediaRecorder.prepare() 之后调用,否则报错"fail to get surface"
  mMediaRecorder.start();

  return Service.START_NOT_STICKY;
 }

 private MediaProjection createMediaProjection() {
  Log.i(TAG, "Create MediaProjection");
  return ((MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE)).getMediaProjection(mResultCode, mResultData);
 }

 private MediaRecorder createMediaRecorder() {
  SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
  Date curDate = new Date(System.currentTimeMillis());
  String curTime = formatter.format(curDate).replace(" ", "");
  String videoQuality = "HD";
  if(isVideoSd) videoQuality = "SD";

  Log.i(TAG, "Create MediaRecorder");
  MediaRecorder mediaRecorder = new MediaRecorder();
//  if(isAudio) mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
  mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  mediaRecorder.setOutputFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/" + videoQuality + curTime + ".mp4");
  mediaRecorder.setVideoSize(mScreenWidth, mScreenHeight); //after setVideoSource(), setOutFormat()
  mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); //after setOutputFormat()
//  if(isAudio) mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //after setOutputFormat()
  int bitRate;
  if(isVideoSd) {
   mediaRecorder.setVideoEncodingBitRate(mScreenWidth * mScreenHeight);
   mediaRecorder.setVideoFrameRate(30);
   bitRate = mScreenWidth * mScreenHeight / 1000;
  } else {
   mediaRecorder.setVideoEncodingBitRate(5 * mScreenWidth * mScreenHeight);
   mediaRecorder.setVideoFrameRate(60); //after setVideoSource(), setOutFormat()
   bitRate = 5 * mScreenWidth * mScreenHeight / 1000;
  }
  try {
   mediaRecorder.prepare();
  } catch (IllegalStateException | IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  Log.i(TAG, "Audio: " + isAudio + ", SD video: " + isVideoSd + ", BitRate: " + bitRate + "kbps");

  return mediaRecorder;
 }

 private VirtualDisplay createVirtualDisplay() {
  Log.i(TAG, "Create VirtualDisplay");
  return mMediaProjection.createVirtualDisplay(TAG, mScreenWidth, mScreenHeight, mScreenDensity,
    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null);
 }

 @Override
 public void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();
  Log.i(TAG, "Service onDestroy");
  if(mVirtualDisplay != null) {
   mVirtualDisplay.release();
   mVirtualDisplay = null;
  }
  if(mMediaRecorder != null) {
   mMediaRecorder.setOnErrorListener(null);
   mMediaProjection.stop();
   mMediaRecorder.reset();
  }
  if(mMediaProjection != null) {
   mMediaProjection.stop();
   mMediaProjection = null;
  }
 }

 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  return null;
 }
}

3、androidManifest.xml权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

4、service的注册

<service android:name=".ScreenRecordService"/>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android录屏功能的实现

    最近做一个Android开发的项目用到了录屏的功能,开始查阅了一些资料和博客,基本上都是在讨论ROOT的.直到后来在github上看到一个比较新的代码,才恍然发现,Android 5.0时候开放了一个新的接口---android.media.projection,一下子让这个问题变得简单了.所以说查阅资料也该注意实时性,现在很多技术推陈出新速度很快,一些新的包,接口,方法会让问题更好更快的解决.不过自己还是决定总结了下之前的一些想法,也算是一个学习吧. 首先说下之前的几种方法.一般最开始的 An

  • android桌面悬浮窗显示录屏时间控制效果

    本文实例为大家分享了android桌面悬浮窗,实现录屏时间控制显示效果的具体代码,供大家参考,具体内容如下 悬浮窗效果如上图所示: 很简单的一个布局直接上代码 悬浮窗布局如下record_screen_time_float.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/an

  • android设置adb自带screenrecord录屏命令

    android 设置system/bin目录类似linux,该目录下有许多实用命令,类似 adb,sh,top,app_process,chmod,chown,dmesg,reboot,screenrecord等等. 录屏作用:qa测试过程中有的bug需要还原现场,此时用手机拍摄有诸多不便,此时可以利用录屏命令自动完成录屏,然后上传bug视频. 其中screenrecord命令录制视频到内部存储: 录制命令: adb shell screenrecord --size 1920x480 /sto

  • Android5.0以上版本录屏实现代码(完整代码)

    我录屏的方式是分别录制音频和视频,最后合并成mp4格式,比较麻烦,因为网上完整的教程比较少,所以我打算写一个完整版的,照着我的代码写完之后,至少是能够实现功能的,而不是简单的介绍下用法. 1既然是录制视频,我们应该有一个按钮控制开始和结束. 2在录制之前,需要先判断一下Android系统的版本是否大于5.0,并且动态申请一下权限(读写,录音,照相机),这一步可以在点开始按钮的时候执行 if (ContextCompat.checkSelfPermission(context, Manifest.

  • android视频截屏&手机录屏实现代码

    本文介绍了android视频截屏&手机录屏实现代码,分享给大家,希望对大家有帮助 问题 在android中有时候我们需要对屏幕进行截屏操作,单一的截屏操作好解决可以通过activity的顶层view DecorView获取一个bitmap,得到就是当前activity上面的全部视图. View view = activity.getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildDrawingCache(

  • Android中手机录屏并转换GIF的两种方式

    之前在博文中为了更好的给大家演示APP的实现效果,本人了解学习了几种给手机录屏的方法,今天就给大家介绍两种我个人用的比较舒服的两种方法: (1)配置adb环境后,使用cmd命令将手机界面操作演示存为视频文件 (2)使用Google浏览器(Google Chrome)提供的扩展程序Vysor将手机界面演示在电脑上(几乎没有延时羡慕) 下面我们具体介绍两种方法的使用步骤: 一.使用cmd命令录屏 (1)SDK下载 网上有各种SDK下载的方法,个人认为安装AndroidStudio后连接自己的手机,根

  • 详解有关Android截图与录屏功能的学习

    简单的截屏和录屏功能. 因为MediaProjection是5.0以上才出现的,所以今天所讲述功能实现,只在5.0以上的系统有效. 截屏: 步骤如下: 1:获取MediaProjectionManager 2:通过MediaProjectionManager.createScreenCaptureIntent()获取Intent 3:通过startActivityForResult传入Intent然后在onActivityResult中通过MediaProjectionManager.getMe

  • android实现录屏功能

    本文实例为大家分享了android实现录屏功能的具体代码,供大家参考,具体内容如下 1.mian.activity package com.fpt.screenvideo; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.media.projection.MediaProjectionManager; import androi

  • android实现录屏小功能

    本文实例为大家分享了android实现录屏小功能的具体代码,供大家参考,具体内容如下 思路 android实现录屏功能有两种方案,一种是直接使用android自带的MediaProjectionManager实现录屏功能,第二种是是只录语音,用户的操作通过某种方式进行记录保存,最后通过某种协议进行播放. 两种方案各有各的优缺点,前者实现方式简单,但无法只录制特定区域的画面,并且生成的视频文件一般都比较大.后者实现较为繁琐,音频录制android7.0之前没有暂停方法,只能生成多个文件,然后对音频

  • Android PC投屏功能实现的示例代码

    本文介绍了Android PC投屏功能实现的示例代码,分享给大家,具体如下: 代码地址 :https://github.com/deepsadness/MediaProjectionDemo 效果预览 投屏效果预览 简单说明: 使用Android MediaProjection Api来完成视频的截图 通过WebSocket进行链接.将图片传递给网页 想法来源 看到vysor,觉得特别好玩,于是就想着自己能不能试着做一个类似的功能出来.搜索了相关实现.发现网上已经有网友针对vysor做了分析.于

  • Android 实现截屏功能的实例

    Android 实现截屏功能的实例 实现代码: public class ScreenShot { // 获取指定Activity的截屏,保存到png文件 private static Bitmap takeScreenShot(Activity activity) { // View是你需要截图的View View view = activity.getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildD

  • python实现录屏功能(亲测好用)

    前言 由与上不了学,教我们Mastercam的老师提前给我们布置了4道习题.对我们太好了,谢谢老师&#55357; 没办法,干就完了. 只是要求附上制作过程视频,就想到了能不能用python做个录屏的程序,于是在网上看了好多文章,发现很多都不是很好用,要不就是太麻烦(我就录个屏,不用声音,也不用控件).最后看到了一个符合我要求的,可以去看看这里(感谢!) 不过呢,俗话说:适合自己的才是最好的.当我们用的时候,会发现录制的时间和视频播放的时间不一致,有的快了,有的慢了,所以就想出了原因与解决办法.接

  • python实现录制全屏和选择区域录屏功能

    最近给客户演示程序运行结果,我就想到用Python写一个录屏程序,在网上能找到现成的源码,但是它的录屏是录制整个屏幕的.但是在屏幕桌面下方的任务栏工具栏里有些东西,不希望被录制到视频里,因此需要实现一个选择区域录屏,就像qq截图那样的.我编写的程序如下,在主函数的输入参数里有一个选项控制是全屏录制还是选择区域录制.在编写这个程序时,我有一个疑问,在初始化写视频VideoWriter函数的第4个参数,它表示视频帧的高和宽,全屏录制方式的参数是(height,width),选择区域录制的参数是(wi

  • python基于tkinter实现gif录屏功能

    一.主界面实现 (一)实现最简单的窗体 from tkinter import * if __name__ == '__main__': tk = Tk() tk.geometry('500x400+500+150') tk.title('有趣的透明窗体-开篇了!!!') canvas = Canvas(tk) canvas.pack(fill=BOTH, expand=Y) tk.mainloop() 太简单了,不详细说了,相信大家都看得懂. (二)把灰色设置成透明色 TRANSCOLOUR

  • 用JS创建一个录屏功能

    OBS studio很酷,但 JavaScript 更酷,现在,我们用 JavaScript 创建自己的录屏功能. 首先,创建一个HTML文件,包含记录按钮和一个播放标签, 内容如下: <!DOCTYPE html> <html> <head> <title>Parcel Sandbox</title> <meta charset="UTF-8" /> </head> <body> <

  • OpenCV实现简单录屏功能

    本文实例为大家分享了OpenCV实现简单录屏功能的具体代码,供大家参考,具体内容如下 OpenCV中VideoCapture和VideoWriter用于读写视频文件,这里的录屏功能用到VideoWriter,用于将捕获的屏幕的每一帧数据保存到视频文件. VideoWriter写视频文件的步骤 1.bool open(const String& filename, int fourcc, double fps,Size frameSize, bool isColor = true);2.void

随机推荐