最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實(shí)現(xiàn)截屏功能

 更新時(shí)間:2021年07月11日 09:55:14   作者:愛(ài)樂(lè)寫(xiě)代碼  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)截屏功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

導(dǎo)言

目前截屏的方法很多,root不適用,要么其他方法就是有局限性,而其中官方給出的方案最好—MediaProjection

介紹

Android 5.0以后開(kāi)放的錄屏API,取視頻中的一幀數(shù)據(jù),這樣就可以實(shí)現(xiàn)截屏

步驟

在activity中授權(quán),在service中完成初始化并截圖,當(dāng)然可以后臺(tái)定時(shí)截圖,但是6.0系統(tǒng)會(huì)有內(nèi)存溢出的bug

1:build.gradle

compileSdkVersion 21
    buildToolsVersion '27.0.3'

    defaultConfig {
        applicationId "com.aile.screenshot"
        multiDexEnabled true
        minSdkVersion 21
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }

2:在activity中授權(quán)

public void requestCapturePermission() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return;
        }
        MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_MEDIA_PROJECTION:
                if (resultCode == RESULT_OK && data != null) {
                    Service.setResultData(data);
                    startService(new Intent(this, Service.class));
                    finish();
                }
                break;
        }
    }

3:在service中初始化ImageReader,MediaProjection

private void createImageReader() {
        mImageReader = ImageReader.newInstance(mScreenWidth, mScreenHeight, PixelFormat.RGBA_8888, 1);
    }
 public void setUpMediaProjection() {
        mMediaProjection = getMediaProjectionManager().getMediaProjection(Activity.RESULT_OK, mResultData);
        }
    }

4:在service中完成截圖重要步驟:

private void startScreenShot() {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                startVirtual();
            }
        }, 0);

        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                startCapture();
            }
        }, 50);
    }
 public void startVirtual() {
        if (mMediaProjection != null) {
            virtualDisplay();
        } else {
            setUpMediaProjection();
            virtualDisplay();
        }
    }
 private void virtualDisplay() {
        mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
                mScreenWidth, mScreenHeight, mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mImageReader.getSurface(), null, null);
    }

//異常處理的核心
private void startCapture() {
        Image image = null;
        try {
            image = mImageReader.acquireLatestImage();
        } catch (IllegalStateException e) {
            if (null != image) {
                image.close();
                image = null;
                image = mImageReader.acquireLatestImage();
            }
        }
        if (image == null) {
            startScreenShot();
        } else {
            SaveTask mSaveTask = new SaveTask();
            AsyncTaskCompat.executeParallel(mSaveTask, image);

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    stopVirtual();
                    tearDownMediaProjection();
                }
            }, 0);
        }
    }
public class SaveTask extends AsyncTask<Image, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(Image... params) {
            if (params == null || params.length < 1 || params[0] == null) {
                return null;
            }
            Image image = params[0];
            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);
            //這就是初始截圖
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
            image.close();
            return bitmap;
        }

        @Override
        protected void onPostExecute(final Bitmap bitmap) {
            super.onPostExecute(bitmap);
            //處理bitmap的業(yè)務(wù)代碼
    }

5:Bitmap轉(zhuǎn)IS流,指定區(qū)域截圖

// 將Bitmap轉(zhuǎn)換成InputStream
   ByteArrayOutputStream bos = new ByteArrayOutputStream();
   bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
   InputStream inputStream = new ByteArrayInputStream(bos.toByteArray());
//指定區(qū)域截圖
   Rect mRect = new Rect(51, 74, 58, 62);
   BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, true);
   Bitmap bm = bitmapRegionDecoder.decodeRegion(mRect, null);

6:定時(shí)任務(wù)的處理

private Timer timer = new Timer();
 public void shootByTime() {
        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                startScreenShot();
                super.handleMessage(msg);
            }
        };
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 1;
                handler.sendMessage(message);
            }
        }, 0, 100);
    }

7:橫豎屏的處理

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == this.getResources().getConfiguration().ORIENTATION_PORTRAIT) {
            mRect = new Rect(51, 775, 745, 47);
        } else if (newConfig.orientation == this.getResources().getConfiguration().ORIENTATION_LANDSCAPE) {
            mRect = new Rect(54, 24, 545, 45);
        }
    }

8:還有很多,只需按照需求走就OK,沒(méi)有難的東西,需要不停的學(xué)習(xí)和積累

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • android handler.post和handler.sendMessage的區(qū)別和聯(lián)系

    android handler.post和handler.sendMessage的區(qū)別和聯(lián)系

    handler.post和handler.sendMessage本質(zhì)上是沒(méi)有區(qū)別的,都是發(fā)送一個(gè)消息到消息隊(duì)列中,而且消息隊(duì)列和handler都是依賴于同一個(gè)線程的。接下來(lái)通過(guò)本文給大家分享android handler.post和handler.sendMessage的區(qū)別和聯(lián)系,一起看看吧
    2017-08-08
  • Android計(jì)時(shí)與倒計(jì)時(shí)實(shí)現(xiàn)限時(shí)搶購(gòu)的5種方法

    Android計(jì)時(shí)與倒計(jì)時(shí)實(shí)現(xiàn)限時(shí)搶購(gòu)的5種方法

    這篇文章主要為大家詳細(xì)介紹了Android計(jì)時(shí)與倒計(jì)時(shí)實(shí)現(xiàn)限時(shí)搶購(gòu)的5種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Android應(yīng)用隱私合規(guī)檢測(cè)實(shí)現(xiàn)方案詳解

    Android應(yīng)用隱私合規(guī)檢測(cè)實(shí)現(xiàn)方案詳解

    這篇文章主要介紹了Android應(yīng)用隱私合規(guī)檢測(cè)實(shí)現(xiàn)方案,我們需要做的就是提前檢測(cè)好自己的應(yīng)用是否存在隱私合規(guī)問(wèn)題,及時(shí)整改過(guò)來(lái),下面提供Xposed Hook思路去檢測(cè)隱私合規(guī)問(wèn)題,建議有Xposed基礎(chǔ)的童鞋閱讀,需要的朋友可以參考下
    2022-07-07
  • Android自定義View實(shí)現(xiàn)拖拽效果

    Android自定義View實(shí)現(xiàn)拖拽效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)拖拽效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Android 通過(guò)Messager與Service實(shí)現(xiàn)進(jìn)程間雙向通信案例詳解

    Android 通過(guò)Messager與Service實(shí)現(xiàn)進(jìn)程間雙向通信案例詳解

    這篇文章主要介紹了Android 通過(guò)Messager與Service實(shí)現(xiàn)進(jìn)程間雙向通信案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Android中button按鈕怎么設(shè)置圓角

    Android中button按鈕怎么設(shè)置圓角

    在android開(kāi)發(fā)中,Button是使用很頻繁的一種控件,而android提供的原生Button是很規(guī)矩的矩形外觀,有時(shí)候缺乏美感,而相反,圓角按鈕則可以提升美感,這篇文章主要給大家介紹了關(guān)于Android中button按鈕怎么設(shè)置圓角的相關(guān)資料,需要的朋友可以參考下
    2023-07-07
  • Android編程獲取組件尺寸大小的方法

    Android編程獲取組件尺寸大小的方法

    這篇文章主要介紹了Android編程獲取組件尺寸大小的方法,結(jié)合實(shí)例形式分析了Android繪制組件之前獲取該組件大小的3種常見(jiàn)操作技巧,需要的朋友可以參考下
    2017-03-03
  • Android實(shí)現(xiàn)畫(huà)板功能(二)

    Android實(shí)現(xiàn)畫(huà)板功能(二)

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)畫(huà)板功能的第二篇,使用imageView,bitmap方式實(shí)現(xiàn)畫(huà)板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Android RefreshLayout實(shí)現(xiàn)下拉刷新布局

    Android RefreshLayout實(shí)現(xiàn)下拉刷新布局

    這篇文章主要為大家詳細(xì)介紹了Android RefreshLayout實(shí)現(xiàn)下拉刷新布局,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Android學(xué)習(xí)教程之日歷控件使用(7)

    Android學(xué)習(xí)教程之日歷控件使用(7)

    這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)教程之日歷控件操作代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11

最新評(píng)論

新乡市| 赤水市| 远安县| 崇文区| 上饶市| 东海县| 苍山县| 左权县| 新龙县| 太保市| 永平县| 道真| 新余市| 临夏市| 绥棱县| 汕尾市| 万山特区| 农安县| 利辛县| 浮梁县| 莱州市| 巴中市| 孝义市| 堆龙德庆县| 农安县| 静宁县| 蕉岭县| 中阳县| 定结县| 十堰市| 洪洞县| 肃南| 麻江县| 黔江区| 邵阳市| 大化| 岳池县| 苗栗县| 蓬溪县| 仲巴县| 吴忠市|