截取当前屏幕截图

时间:2012-02-04 00:50:08

标签: android screenshot

我找到了这段代码。这应该是读取帧缓冲并将其保存为png文件。

它给出了错误:

eglCreateWindowSurface() can only be called with an instance 
of SurfaceView or SurfaceHolder at the moment, this will be fixed later.

代码:

    private EGL10 egl;
    private EGLDisplay display;
    private EGLConfig config; 
    private EGLSurface surface;
    private EGLContext eglContext;
    private GL11 gl;
    //private GL10 gl10;
    protected int width, height;
    Bitmap mSavedBM;

    public void Take(Context context)
    {
        Display display= ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();        
        int screenWidth = display.getWidth();
        int screenHeight = display.getHeight();     
        String SCREENSHOT_DIR = "/sdcard/screenshots";
        initGLFr(); //GlView initialized.
        savePixels( 0, 10, screenWidth, screenHeight, gl); //this gets the screen to the mSavedBM.
        saveBitmap(mSavedBM, SCREENSHOT_DIR, "capturedImage");
    }

    private void initGLFr()
    {
        egl = (EGL10) EGLContext.getEGL();
        display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
        int[] ver = new int[2];
        egl.eglInitialize(display, ver);
        int[] configSpec = {EGL10.EGL_NONE};
        EGLConfig[] configOut = new EGLConfig[1];
        int[] nConfig = new int[1];
        egl.eglChooseConfig(display, configSpec, configOut, 1, nConfig);
        config = configOut[0];
        eglContext = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null);
        surface = egl.eglCreateWindowSurface(display, config, SurfaceHolder.SURFACE_TYPE_GPU, null);
        egl.eglMakeCurrent(display, surface, surface, eglContext);
        gl = (GL11) eglContext.getGL();
    }

    public void savePixels(int x, int y, int w, int h, GL10 gl)
    {
        if (gl == null)
        {
            return;         
        }
        synchronized (this)
        {
            if (mSavedBM != null) 
            {
                mSavedBM.recycle();
                mSavedBM = null;
            }
        }
        int b[] = new int[w * (y + h)];
        int bt[] = new int[w * h];
        IntBuffer ib = IntBuffer.wrap(b);
        ib.position(0);
        gl.glReadPixels(x, 0, w, y + h, GL10.GL_RGBA,GL10.GL_UNSIGNED_BYTE,ib);
        for (int i = 0, k = 0; i < h; i++, k++)
        {
            //OpenGLbitmap is incompatible with Android bitmap
            //and so, some corrections need to be done.
            for (int j = 0; j < w; j++)
            {
                int pix = b[i * w + j];
                int pb = (pix >> 16) & 0xff;
                int pr = (pix << 16) & 0x00ff0000;
                int pix1 = (pix & 0xff00ff00) | pr | pb;
                bt[(h - k - 1) * w + j] = pix1;
            }
        }
        Bitmap sb = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
        synchronized (this)
        {
            mSavedBM = sb;
        }
    } 

    static String saveBitmap(Bitmap bitmap, String dir, String baseName) 
    {
        try 
        {
            File sdcard = Environment.getExternalStorageDirectory();
            File pictureDir = new File(sdcard, dir);
            pictureDir.mkdirs();
            File f = null;
            for (int i = 1; i < 200; ++i)
            {
                String name = baseName + i + ".png";
                f = new File(pictureDir, name);
                if (!f.exists()) 
                {
                    break;
                }
            }
            if (!f.exists()) 
            {
                String name = f.getAbsolutePath();
                FileOutputStream fos = new FileOutputStream(name);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                fos.flush();
                fos.close();
                return name;
            }
        }
        catch (Exception e) {} 
        return null;
    }

}

问题:

此代码是否在我的应用程序处于后台时或者仅显示我的应用程序的屏幕截图时截取屏幕截图?

2 个答案:

答案 0 :(得分:4)

您无法截屏(这可能是一个安全漏洞),只有系统应用可以执行此操作。 这种方法很可能会保存黑色PNG。

答案 1 :(得分:1)

您需要根据自己的设备生根,否则无法工作。此外,你必须让你的应用程序获得超级用户访问权限。只需实现此代码,您就可以了:

public void screenShot() throws InterruptedException
{
    Process sh;
    try
    {
        sh = Runtime.getRuntime().exec("su", null, null);
        OutputStream os = sh.getOutputStream();
        os.write(("/system/bin/screencap -p " + "/sdcard/Image.png").getBytes("ASCII"));
        os.flush();
        os.close();
        sh.waitFor();
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}