Take a photo using a service on OnePlus One - using WindowManager hack

被刻印的时光 ゝ 提交于 2019-11-28 05:27:30

问题


I'm trying to take a picture without showing the user anything (no view) through a service. This question has been asked several times before and I've gone through all I could find. Some similar questions:

  • Android Camera.takePicture failed

  • Android camera fails to take photo from background service

Most of the questions link to other questions without providing a new solution.

I believe this is the best way to solve this problem: https://stackoverflow.com/a/10268650/3860594 Unfortunately the person has not provided a complete answer and I'm having trouble reproducing his method.

What I'm trying to do is create a SurfaceView inside a SurfaceHolder. I will then use WindowManager with the SurfaceView to create a floating window of sorts that is completely transparent so that it's hidden from the user. Please correct me if I'm wrong.

Here is my code:

SurfaceView mview = new SurfaceView(this);
SurfaceHolder mholder = new SurfaceHolder() {
    @Override
    public void addCallback(Callback callback) {

    }

    @Override
    public void removeCallback(Callback callback) {

    }

    @Override
    public boolean isCreating() {
        return false;
    }

    @Override
    public void setType(int type) {

    }

    @Override
        public void setFixedSize(int width, int height) {
    }

    @Override
    public void setSizeFromLayout() {
    }

    @Override
    public void setFormat(int format) {

    }

    @Override
    public void setKeepScreenOn(boolean screenOn) {
    }

    @Override
    public Canvas lockCanvas() {
        return null;
    }

    @Override
    public Canvas lockCanvas(Rect dirty) {
        return null;
    }

    @Override
        public void unlockCanvasAndPost(Canvas canvas) {

    }

    @Override
    public Rect getSurfaceFrame() {
        return null;
    }

    @Override
    public Surface getSurface() {
        return null;
    }
};


WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
        PixelFormat.TRANSLUCENT);
wm.addView(mview, params);
mview.setZOrderOnTop(true);
mholder.setFormat(PixelFormat.TRANSPARENT);


try {
    camera.setPreviewDisplay(mview.getHolder());
    camera.startPreview();
    camera.takePicture(null,null,photoCallback);
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

None of this works as the usual message RuntimeException: takePicture failed is shown. Any help would be awesome, thanks.


回答1:


It happens so that the last brick in the puzzle was only revealed a week after the question was asked. The problem is specific to a particular device, namely, OnePlus One.

The sample code at https://github.com/alexcohn/CameraInService shows how this can be handled; the latest commit adds a delay between starting preview and performing takePicture(). The experiment on my wife's OnePlus One shows that delay of 100 ms is OK, but 1 ms is too short.



来源:https://stackoverflow.com/questions/32779706/take-a-photo-using-a-service-on-oneplus-one-using-windowmanager-hack

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!