Android 截屏 录屏 与获取log

简介: Android 截屏 录屏 与获取log

1.截屏

1.申请权限

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

2.创建service 拉起媒体服务

public class RecordService extends Service {
 
    public static MediaProjection mMediaProjection;
    MediaProjectionManager mMediaProjectionManager;
    boolean isMediaRecording;
    VirtualDisplay virtualDisplay;
    private MediaRecorder mediaRecorder;
    int width ;
    int height ;
    int dpi ;
    String filePathName;
    public RecordService() {
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
 
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        createNotificationChannel();
        int mResultCode = intent.getIntExtra("code", -1);
        Intent mResultData = intent.getParcelableExtra("data");
        int action = intent.getIntExtra("action", 0);
        width = intent.getIntExtra("width", 0);
        height = intent.getIntExtra("height", 0);
        dpi = intent.getIntExtra("dpi", 0);
 
        Log.e("test",width +"     "+height+"       "+dpi);
        //mResultData = intent.getSelector();
        mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        mMediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, mResultData);
        if(action == 0){
            takePhoto();
        }
        else if(action ==1){
            try {
                recordScreen();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
        stopRecording();
    }
 
    private void recordScreen() throws InterruptedException {
        Log.e("test","recordScreen");
        createMediaRecorder();
        //@SuppressLint("WrongConstant") ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 3);
        if(virtualDisplay == null){
            virtualDisplay = mMediaProjection.createVirtualDisplay("screen_shot",
                    width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                    mediaRecorder.getSurface(), null, null);
        }
       else {
            virtualDisplay.setSurface(mediaRecorder.getSurface());
        }
 
        startRecording();
    }
 
    /**
     * 开始 媒体录制
     *
     *
     */
    public void startRecording() {
        //createMediaRecorder();
        mediaRecorder.start();
        isMediaRecording = true;
    }
 
 
 
    /**
     * 停止 媒体录制
     */
    public void stopRecording() {
        mediaRecorder.stop();
        mediaRecorder.reset();
        mediaRecorder.release();
        mediaRecorder = null;
        isMediaRecording = false;
        filePathName = null;
    }
 
 
    private MediaRecorder createMediaRecorder() {
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        String filePath=Environment.getExternalStorageDirectory()+"/ScreenVideo/";
        if(!new File(filePath).exists()){
            new File(filePath).mkdirs();
        }
        filePathName= filePath+simpleDateFormat.format(new Date())+".mp4";
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setOutputFile(filePathName);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setVideoSize(width, height);
        mediaRecorder.setVideoFrameRate(60);
        mediaRecorder.setVideoEncodingBitRate(5 * width * height);
        try{
            mediaRecorder.prepare();
        }catch (Exception e){
            e.printStackTrace();
        }
        return mediaRecorder;
    }
 
    public void takePhoto(){
        @SuppressLint("WrongConstant") ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 3);
        mMediaProjection.createVirtualDisplay("screen_shot",
                width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                imageReader.getSurface(), null, null);
        imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {
                Image image = reader.acquireNextImage();//获取下一帧截屏,这里可以控制你是否要单个或者直接录屏
                int width = image.getWidth();
                int height = image.getHeight();
                final Image.Plane[] planes = image.getPlanes();
                final ByteBuffer buffer = planes[0].getBuffer();
                int pixelStride = planes[0].getPixelStride();
                int rowStride = planes[0].getRowStride();
                int rowPadding = rowStride - pixelStride * width;
                Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
                bitmap.copyPixelsFromBuffer(buffer);
                if (bitmap != null) {
                    try {
                        // 获取内置SD卡路径
                        String sdCardPath = Environment.getExternalStorageDirectory().getPath();
                        Log.e("test",sdCardPath);
                        // 图片文件路径
                        String filePath = sdCardPath + File.separator + System.currentTimeMillis()+".png";
                        File file = new File(filePath);
                        FileOutputStream fos = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                        fos.flush();
                        fos.close();
                        Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_SHORT).show();
                        Log.e("1111111","保存成功");
                        reader.close();
                    } catch (Exception e) {
                        Log.e("test",e.toString());
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "bitmap == null", Toast.LENGTH_SHORT).show();
                }
                image.close();
            }
        }, null);
    }
 
    private void createNotificationChannel() {
        Notification.Builder builder = new Notification.Builder(this.getApplicationContext()); //获取一个Notification构造器
        Intent nfIntent = new Intent(this, MainActivity.class); //点击后跳转的界面,可以设置跳转数据
 
        builder.setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0)) // 设置PendingIntent
                .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标)
                //.setContentTitle("SMI InstantView") // 设置下拉列表里的标题
                .setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
                .setContentText("is running......") // 设置上下文内容
                .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间
 
        /*以下是对Android 8.0的适配*/
        //普通notification适配
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId("notification_id");
        }
        //前台服务notification适配
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
            NotificationChannel channel = new NotificationChannel("notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW);
            notificationManager.createNotificationChannel(channel);
        }
 
        Notification notification = builder.build(); // 获取构建好的Notification
        notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
        startForeground(110, notification);
    }
}

3.MainActivity

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    Button btn_take,btn_record,btn_log,btn_stopLog;
    MediaProjectionManager mediaProjectionManager;
    int width, height, dpi;
    static int TAKEPHOTO = 0;
    static int RECORDSCREEN = 1;
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_record = findViewById(R.id.recordscreen);
        btn_take = findViewById(R.id.takephoto);
        btn_log = findViewById(R.id.getLog);
        btn_stopLog = findViewById(R.id.stopLog);
        getPermission();
        LogUtils logUtils = new LogUtils();
        btn_log.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                logUtils.getLog("logcat");
            }
        });
 
        btn_stopLog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                logUtils.stopLog();
            }
        });
 
        btn_take.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startScreenShot();
            }
        });
 
        btn_record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               stopService(new Intent(MainActivity.this,RecordService.class));
            }
        });
    }
 
 
 
    private void startScreenShot() {
        WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        if (windowManager != null) {
            DisplayMetrics displayMetrics = new DisplayMetrics();
            windowManager.getDefaultDisplay().getMetrics(displayMetrics);
            width = displayMetrics.widthPixels;
            height = displayMetrics.heightPixels;
            dpi = displayMetrics.densityDpi;
            Log.e("test",width +"     "+height+"       "+dpi);
        }
 
 
        mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        if (mediaProjectionManager != null) {
            startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 10086);
        }
    }
 
    /**
     * @param requestCode
     * @param resultCode
     * @param data
     */
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_CANCELED) {
            Log.e(TAG, "User cancel");
        } else {
            Intent service = new Intent(this, RecordService.class);
            service.putExtra("code", resultCode);
            service.putExtra("data", data);
            service.putExtra("action",RECORDSCREEN);
            service.putExtra("width",width);
            service.putExtra("height",height);
            service.putExtra("dpi",dpi);
            startForegroundService(service);
        }
 
 
//        width = 500;
//        height = 500;
//        dpi = 10;
 
 
    }
 
    public void getPermission(){
        try{
            //需要的权限
            String[] permArr={
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS,
            };
            boolean needReq = false;
            for(int i=0;i<permArr.length;i++){
                if(ContextCompat.checkSelfPermission(this, permArr[i])!= PackageManager.PERMISSION_GRANTED){
                    needReq = true;
                    break;
                }
            }
            if(needReq)
                ActivityCompat.requestPermissions(this,permArr,1);
        }catch (Exception e){
            Log.w("动态申请权限时,发生异常。",e);
        }
    }
 
 
}

3.LogUtils

 public void getLog(String command){
        new Thread(new Runnable() {
            @Override
            public void run() {
                FileOutputStream os = null;
                Process p = null;
                try {
                    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
                    Runtime.getRuntime().exec("logcat -c");
                    p = Runtime.getRuntime().exec(command);
                    InputStream is = p.getInputStream();
                    File file = new File(sdCardPath+"/log/"+simpleDateFormat.format(new Date())+".log");
                    if(!file.exists()) {
                        //先得到文件的上级目录,并创建上级目录,在创建文件
                        file.getParentFile().mkdir();
                        try {
                            //创建文件
                            file.createNewFile();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    os = new FileOutputStream(file);
                    int len = 0;
                    byte[] buf = new byte[1024];
                    while ((-1 != (len = is.read(buf)))) {
                        os.write(buf, 0, len);
                    }
                } catch (IOException e) {
                    Log.e("test",e.toString());
                    e.printStackTrace();
                }finally {
                    Log.e("test","finally");
                    try {
                        os.flush();
                        os.close();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
 
                }
            }
        }).start();
    }


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4天前
|
监控 Android开发 C语言
深度解读Android崩溃日志案例分析2:tombstone日志
深度解读Android崩溃日志案例分析2:tombstone日志
101 0
|
2天前
|
监控 安全 API
orhanobut/logger - 强大的Android日志打印库
orhanobut/logger - 强大的Android日志打印库
8 1
|
4天前
|
Android开发
Android Mediatek 禁用 UART 日志输出
Android Mediatek 禁用 UART 日志输出
11 0
|
4天前
|
存储 缓存 监控
通过bugly日志分析,了解到的Android盲区知识
通过bugly日志分析,了解到的Android盲区知识
81 0
|
5月前
|
网络协议 Android开发 虚拟化
Android Studio无法运行程序调试程序出现Unable to connect to ADB.Check the Event Log for possible issues.Verify th
Android Studio无法运行程序调试程序出现Unable to connect to ADB.Check the Event Log for possible issues.Verify th
64 0
Android Studio无法运行程序调试程序出现Unable to connect to ADB.Check the Event Log for possible issues.Verify th
|
6月前
|
编译器 Android开发
深度解读Android崩溃日志案例分析1:so崩溃
深度解读Android崩溃日志案例分析1:so崩溃
117 1
|
8月前
|
编解码 Android开发 数据安全/隐私保护
如何在Android实现录屏直播
许多开发者在做智慧教室同屏亦或会议同屏时,基于Andriod平台采集屏幕并编码推送,往往遇到各种各样的问题,以下就我们开发过程中的一些技术考量做个分享,权当抛砖引玉:
164 2
|
9月前
|
Android开发
Android Log类中方法的使用
Android Log类中方法的使用
61 0
|
2天前
|
关系型数据库 MySQL 数据库
mysql数据库bin-log日志管理
mysql数据库bin-log日志管理
|
2天前
|
存储 关系型数据库 数据库
关系型数据库文件方式存储LOG FILE(日志文件)
【5月更文挑战第11天】关系型数据库文件方式存储LOG FILE(日志文件)
7 1