本文基于android6.0。首先找到screencap在Android源码中的位置,若不清楚,可以通过在android目录下通过命令find . -namescreencap.cpp。本文直接给出路径/android/frameworks/base/cmds/screencap/screencap.cpp。入口函数为main,只要编译就可以直接使用。如果需要将数据传出来,需要利用socket,后面会更新,将当前屏幕信息实时传输到web端显示。data->data(), data->size()是需求的数据和大小)。

screencap.cpp源码如下:

/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include #include #include #include #include #include #include #include #include #include #include #include #include #include // TODO: Fix Skia.#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wunused-parameter"#include #include #pragma GCC diagnostic popusing namespace android;static uint32_t DEFAULT_DISPLAY_ID = ISurfaceComposer::eDisplayIdMain;//eDisplayIdMain = 0static void usage(const char* pname){    fprintf(stderr,            "usage: %s [-hp] [-d display-id] [FILENAME]\n"            "   -h: this message\n"            "   -p: save the file as a png.\n"            "   -d: specify the display id to capture, default %d.\n"            "If FILENAME ends with .png it will be saved as a png.\n"            "If FILENAME is not given, the results will be printed to stdout.\n",            pname, DEFAULT_DISPLAY_ID    );}static SkColorType flinger2skia(PixelFormat f){    switch (f) {        case PIXEL_FORMAT_RGB_565:            return kRGB_565_SkColorType;        default:            return kN32_SkColorType;    }}static status_t vinfoToPixelFormat(const fb_var_screeninfo& vinfo,        uint32_t* bytespp, uint32_t* f){    switch (vinfo.bits_per_pixel) {        case 16:            *f = PIXEL_FORMAT_RGB_565;            *bytespp = 2;            break;        case 24:            *f = PIXEL_FORMAT_RGB_888;            *bytespp = 3;            break;        case 32:            // TODO: do better decoding of vinfo here            *f = PIXEL_FORMAT_RGBX_8888;            *bytespp = 4;            break;        default:            return BAD_VALUE;    }    return NO_ERROR;}static status_t notifyMediaScanner(const char* fileName) {    String8 cmd("am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file://");    String8 fileUrl("\"");    fileUrl.append(fileName);    fileUrl.append("\"");    cmd.append(fileName);    cmd.append(" > /dev/null");    int result = system(cmd.string());    if (result < 0) {        fprintf(stderr, "Unable to broadcast intent for media scanner.\n");        return UNKNOWN_ERROR;    }    return NO_ERROR;}int main(int argc, char** argv){    //while(1){        //创建ProcessState 当前进程属性,启动进程的线程池    ProcessState::self()->startThreadPool();        const char* pname = argv[0];    bool png = false;    int32_t displayId = DEFAULT_DISPLAY_ID;//DEFAULT_DISPLAY_ID = eDisplayIdMain = 0,    int c;    while ((c = getopt(argc, argv, "phd:")) != -1) {        switch (c) {            case 'p':                png = true;                break;            case 'd':                displayId = atoi(optarg);                break;            case '?':            case 'h':                usage(pname);                return 1;        }    }    argc -= optind;//optind = 1    argv += optind;    struct timeval tv;  //超时时间设置    while(1){        gettimeofday(&tv,NULL);        ALOGE("tv.tv_sec = %ld ,tv.tv_usec = %ld\n", tv.tv_sec, tv.tv_usec);        int fd = -1;        const char* fn = NULL;        if (argc == 0) {            fd = dup(STDOUT_FILENO);//STDOUT_FILENO=1        } else if (argc == 1) {            fn = argv[0];            fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);            if (fd == -1) {                fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno));                return 1;            }            const int len = strlen(fn);            if (len >= 4 && 0 == strcmp(fn+len-4, ".png")) {                png = true;            }        }            if (fd == -1) {            usage(pname);            return 1;        }//------------------------------------------------------------------------------------        void const* mapbase = MAP_FAILED;    ssize_t mapsize = -1;    void const* base = NULL;    uint32_t w, s, h, f;    size_t size = 0;    // Maps orientations from DisplayInfo to ISurfaceComposer    static const uint32_t ORIENTATION_MAP[] = {        ISurfaceComposer::eRotateNone, // 0 == DISPLAY_ORIENTATION_0        ISurfaceComposer::eRotate270, // 1 == DISPLAY_ORIENTATION_90        ISurfaceComposer::eRotate180, // 2 == DISPLAY_ORIENTATION_180        ISurfaceComposer::eRotate90, // 3 == DISPLAY_ORIENTATION_270    };//------------------------------------------------------------------------------------    ScreenshotClient screenshot;    sp display = SurfaceComposerClient::getBuiltInDisplay(displayId);    if (display == NULL) {        fprintf(stderr, "Unable to get handle for display %d\n", displayId);        return 1;    }    Vector configs;    SurfaceComposerClient::getDisplayConfigs(display, &configs);    int activeConfig = SurfaceComposerClient::getActiveConfig(display);    if (static_cast(activeConfig) >= configs.size()) {        fprintf(stderr, "Active config %d not inside configs (size %zu)\n",                activeConfig, configs.size());        return 1;    }    uint8_t displayOrientation = configs[activeConfig].orientation;    uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];    status_t result = screenshot.update(display, Rect(), 0, 0, 0, -1U,            false, captureOrientation);    if (result == NO_ERROR) {        base = screenshot.getPixels();        w = screenshot.getWidth();        h = screenshot.getHeight();        s = screenshot.getStride();        f = screenshot.getFormat();        size = screenshot.getSize();    } else {         const char* fbpath = "/dev/graphics/fb0";        int fb = open(fbpath, O_RDONLY);        if (fb >= 0) {            struct fb_var_screeninfo vinfo;            if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) == 0) {                uint32_t bytespp;                if (vinfoToPixelFormat(vinfo, &bytespp, &f) == NO_ERROR) {                    size_t offset = (vinfo.xoffset + vinfo.yoffset*vinfo.xres) * bytespp;                    w = vinfo.xres;                    h = vinfo.yres;                    s = vinfo.xres;                    size = w*h*bytespp;                    mapsize = offset + size;                    mapbase = mmap(0, mapsize, PROT_READ, MAP_PRIVATE, fb, 0);                    if (mapbase != MAP_FAILED) {                        base = (void const *)((char const *)mapbase + offset);                    }                }            }            close(fb);        }    }        if (base != NULL) {        if (png) {            const SkImageInfo info = SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType);            SkAutoTUnref data(SkImageEncoder::EncodeData(info, base, s*bytesPerPixel(f),                    SkImageEncoder::kJPEG_Type, SkImageEncoder::kDefaultQuality));            if (data.get()) {                FILE *fp;                  if((fp=fopen("/data/audioBuffer.txt","a+"))==NULL) {                      ALOGE("00000000000000000\n");                   }                  else {                             fwrite(data->data(),data->size(),1, fp);                    ALOGE("data->size() = %zu\n",data->size());                                     }                 fclose(fp);                write(fd, data->data(), data->size()); //data->data(), data->size()可以将数据传出去实时录制当前屏幕            }            if (fn != NULL) {                notifyMediaScanner(fn);            }        } else {            write(fd, &w, 4);            write(fd, &h, 4);            write(fd, &f, 4);            size_t Bpp = bytesPerPixel(f);            for (size_t y=0 ; y


 修改后进行编译:   

source build/envsetup.sh

lunch 6

make -j8


运行模拟器:emulator -sdcard /home/bruceking90/Documents/workplace/sdcard.img &


之后进行截屏:adb shell screencap -p | sed 's/\r$//' > screen.png

此命令可以直接将png存放在android即当前目录下。

或者adb shell screencap -p /sdcard/screen.png


sdcard创建可以参考:http://blog.csdn.net/ctrl_qun/article/details/52524993

点对点socket传输数据参考:http://blog.csdn.net/ctrl_qun/article/details/52454151

多个客户端socket传输数据参考:http://blog.csdn.net/ctrl_qun/article/details/52524086



更多相关文章

  1. [Android(安卓)Studio]-基本快捷键大全
  2. Android中使用Build获取当前系统SDK版本
  3. Android之间互相的录屏直播 --点对点传输(tcp长连接发送h264)(一
  4. Android通过ADB命令获取当前运行的Activity
  5. Android(安卓)3.0 r1中文API文档(103) ―― InputMethodManager
  6. Android获取当前已连接的wifi信号强度的方法
  7. android studio使用快捷键大全
  8. Android(安卓)Layout XML属性
  9. Android封装jar包,把当前项目设置成module,封装手机振动jar包给uni

随机推荐

  1. Android没有必要诋毁iPhone
  2. [置顶] [Android(安卓)Studio 权威教程]断
  3. Android(安卓)Studio获取SHA1和MD5值---
  4. Android各种通用模块总结
  5. Android通过原生APi获取所在位置的经纬度
  6. Android布局管理器总结一:LinearLayout
  7. Android(安卓)优秀源码收集方式
  8. 9、Libgdx的输入处理
  9. Android学习之shape属性与用法
  10. Android(安卓)淘气三千传之 —— 插件化