Android-Camera App传递了空表面

Bir*_*tus 1 service camera android surfaceview

我已经尝试过在stackoverflow上给出的所有可能解决方案,但仍达不到我想要的。我想使用带有服务的Camera API拍照。当用户点亮屏幕时应拍照,但屏幕仍处于锁定状态。我看到了有关虚拟表面等的不同文章...但是它们都不起作用,当然,因为我是Camera API的新手,所以我肯定在代码中犯了错误。我的应用程序是这样进行的:我安排AlarmManager启动服务:

public int onStartCommand(Intent intent,int flags,int startId) {
        Log.i("service","start");
        Calendar finServ=Calendar.getInstance();
        String all=intent.getStringExtra("all");
        nomevt=all.split(Pattern.quote("**"))[3];
        Scanner sc;
        String str="";
        try {
            sc = new Scanner(new File(getFilesDir(),"Event.evt"));
            while(sc.hasNext()) {
                str=sc.next();
                if(all.equals(str)) break;
            }
            sc.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if(!all.equals(str)) stopSelf();
        else {
            finServ.setTimeInMillis(toMillis(str.split(Pattern.quote("**"))[1]));
            Calendar now=Calendar.getInstance();
            now.setTime(new Date());
            while(finServ.after(now)) {
                PowerManager pm=(PowerManager)getSystemService(Context.POWER_SERVICE);
                if(pm.isScreenOn()) {
                    //AsyncCapture ac=new AsyncCapture(this);
                    //ac.execute("nomevt");
                    photo();
                    Log.i("screen","on");
                    while(pm.isScreenOn()) {
                        pm=(PowerManager)getSystemService(Context.POWER_SERVICE);
                    }
                }
                now.setTime(new Date());
            }
            stopSelf();
        }
        return super.onStartCommand(intent, flags, startId);
    }`
<br>The service will call `photo()` when the screen is light on. <br> 
`public void photo() {
        cam=Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
        try {
            cam.unlock();
            /*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);*/
            SurfaceView sv=new SurfaceView(this);
            //wm.addView(sv, params);
            ViewGroup.LayoutParams param=new ViewGroup.LayoutParams(1,1);
            sv.setLayoutParams(param);
            sv.setZOrderOnTop(true);
            SurfaceHolder mHolder=sv.getHolder();
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            Log.i("holder",(mHolder==null)+"");
            cam.setPreviewDisplay(mHolder);
            cam.startPreview();
            cam.takePicture(null,null,this);
            //wm.removeView(sv);
            Log.i("take","picture");
        } catch (IOException e) {
            Log.e("error",e.getMessage());
            e.printStackTrace();
        }catch(RuntimeException re) {
            Log.e("error",re.getMessage()+"");
            re.printStackTrace();
        }finally{
            cam.stopPreview();
            cam.release();
        }
    }
Run Code Online (Sandbox Code Playgroud)

而且,在takePicture()我仅保存图像的过程中,此方法就可以在活动中对其进行测试。日志显示错误Camera : app passed NULL surfaceerror : setPreviewTextureFailed。我放入日志以查看是否mHolder为空,但不是。
为什么会setPreviewDisplay()引发错误?

Cà *_*đen 5

您应该使用SurfaceTexturesetPreviewTexture()而不是SurfaceHolder

SurfaceTexture surfaceTexture = new SurfaceTexture(0);
cam.setPreviewTexture(surfaceTexture);
Run Code Online (Sandbox Code Playgroud)

Camera : app passed NULL surface引发该错误setPreviewDisplay()是因为没有创建曲面。

如果仍要使用SurfaceHolder,则应SurfaceHolder.Callback首先实现setPreviewDisplay()in surfaceCreated()方法,以确保在创建曲面之前就已创建setPreviewDisplay()

请注意,只有将其添加到“视图”层次结构中之后,该表面才会创建。

编辑

当您setPreviewTexture()由于使用过cam.unlock();相机而返回错误时,您的相机被暂时释放以供其他进程使用在此处了解有关unlock()方法的更多信息)。这就是为什么在致电时出错。java.io.IOException: setPreviewTexture failedsetPreviewTexture()

解决的方法是删除cam.unlock();代码中的行。