Сфотографируйте с помощью сервиса на OnePlus One - с помощью взлома WindowManager

Я пытаюсь сделать снимок, не показывая пользователю ничего (без просмотра) через сервис. Этот вопрос задавался несколько раз прежде, и я прошел через все, что мог найти. Несколько похожих вопросов:

Большинство вопросов связаны с другими вопросами без предоставления нового решения.

Я считаю, что это лучший способ решить эту проблему: /questions/32106588/fotosemka-s-kameryi-bez-predvaritelnogo-prosmotra/32106598#32106598 К сожалению, этот человек не дал полного ответа, и у меня возникли проблемы с воспроизведением его метода.

То, что я пытаюсь сделать, это создать SurfaceView внутри SurfaceHolder. Затем я буду использовать WindowManager с SurfaceView для создания полностью прозрачного плавающего окна, которое будет скрыто от пользователя. Пожалуйста, поправьте меня, если я ошибаюсь.

Вот мой код:

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();
}

Ничто из этого не работает как обычное сообщение RuntimeException: takePicture failed Показано. Любая помощь будет потрясающей, спасибо.

1 ответ

Решение

Случилось так, что последний кирпич в загадке был обнаружен только через неделю после того, как был задан вопрос. Проблема специфична для конкретного устройства, а именно OnePlus One.

Пример кода на https://github.com/alexcohn/CameraInService показывает, как это можно сделать; последний коммит добавляет задержку между запуском предварительного просмотра и выполнением takePicture (). Эксперимент на OnePlus One моей жены показывает, что задержка в 100 мс - это нормально, но 1 мс слишком коротка.

Другие вопросы по тегам