我已经尝试了 stackoverflow 上给出的所有可能的解决方案,但仍然没有达到我想要的效果。我想用带有服务的 Camera API 拍照。当用户点亮屏幕时应该拍照,但屏幕仍处于锁定状态。我看到了关于虚拟表面等的不同帖子......但它们都不起作用,当然我一定是在我的代码中犯了错误,因为我是相机 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();
}
}
在 takePicture()
中,我只是保存图像,这个方法在我在 Activity 中测试时有效。
日志显示错误 Camera : app passed NULL surface
, error : setPreviewTextureFailed
。我放了一个日志来查看 mHolder
是否为 null 但它不是。
为什么 setPreviewDisplay()
会抛出错误?
最佳答案
您应该使用 SurfaceTexture
和 setPreviewTexture()
而不是 SurfaceHolder
:
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
cam.setPreviewTexture(surfaceTexture);
错误 Camera : app passed NULL surface
has been throwed in setPreviewDisplay()
is because there are no surface created.
如果你仍然想使用SurfaceHolder
,你应该先实现SurfaceHolder.Callback
,然后在surfaceCreated()中实现
方法以确保在您 setPreviewDisplay()
setPreviewDisplay()
之前创建表面。
请注意,在将表面添加到 View 层次结构之前,不会创建表面。
编辑
回到你在 setPreviewTexture()
时的错误,因为你使用了 cam.unlock();
,你的相机 暂时释放给另一个进程使用(阅读更多关于 unlock()
方法 here )。这就是当您调用 setPreviewTexture()
时出现错误 java.io.IOException: setPreviewTexture failed
的原因。
解决方案是删除代码中的 cam.unlock();
行。
关于Android - 相机应用程序通过了空表面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30616097/