我开发了一个锁屏,而用户错误的尝试相机应该自动启动并拍照,但我没有找到任何解决方案或API
此代码首先声明将作为Surface视图和activity_main.xml文件中的图像视图的句柄的变量。然后,声明一个Bitmap对象,它将用于在捕获后显示图像(第23行)。之后,声明了3个对象:一个SurfaceHolder,它将分配一部分屏幕来渲染相机预览(其宽度和高度为0);一台可以处理设备相机的相机;和一个Parameters对象,用于设置摄像机的设置(第27到31行)。
继续使用onCreate()方法,它基本上通过获取对其他现有对象的引用来初始化所有声明的对象,例如将在main.xml文件中引用SurfaceView的sv对象。此方法中有两行需要更详细的说明。第50行将Surface Holder回调设置为此,因为此类正在实现SurfaceHolder.Callback接口,其目的是控制“表面”(屏幕区域)的渲染。这是必需的,以便“预览”有效。另一个重要的是第53行,告诉Android这个表面将替换所有数据。
SurfaceChanged()方法就是这一切。初始化参数对象(第60行)。不仅如此,还设置了摄像机参数,并开始预览(第63和64行)。定义了图像回调,每次拍照时都会调用它的代码(第67到77行)。在其中,摄像机捕获的数据被解码为Bitmap对象(第73行),然后,第75行告诉ImageView显示此位图。在方法结束时,要求摄像机使用最近创建的回调拍摄照片(第79行)。
surfaceCreated()方法中的代码将相机对象挂钩到设备的相机。它还告诉摄像机应该预览其捕获的位置(第83到95行)。最后一个方法是surfaceDestroyed()方法释放相机,因此它可以被其他应用程序使用(第98到106行)。
这是一个非常标准的相机捕捉代码。隐藏预览的是Surface Holder的宽度和高度,它们设置为零。使其工作所需的最后一项要求是添加访问AndroidManifest文件的相机权限:
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
MainActivity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
display=(ImageView)findViewById(R.id.imageView1);
// do we have a camera?
if (!getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
.show();
} else {
cameraId = findFrontFacingCamera();
if (cameraId < 0) {
Toast.makeText(this, "No front facing camera found.",
Toast.LENGTH_LONG).show();
} else {
safeCameraOpen(cameraId);
}
}
// THIS IS JUST A FAKE SURFACE TO TRICK THE CAMERA PREVIEW
// http://stackoverflow.com/questions/17859777/how-to-take-pictures-in-android-
// application-without-the-user-interface
SurfaceView view = new SurfaceView(this);
try {
camera.setPreviewDisplay(view.getHolder());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
Camera.Parameters params = camera.getParameters();
params.setJpegQuality(100);
camera.setParameters(params);
// We need something to trigger periodically the capture of a
// picture to be processed
timer=new Timer(getApplicationContext(),threadHandler);
timer.execute();
}
////////////////////////////////////thread Handler///////////////////////////////////////
private Handler threadHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case DONE:
// Trigger camera callback to take pic
camera.takePicture(null, null, mCall);
break;
case NEXT:
timer=new Timer(getApplicationContext(),threadHandler);
timer.execute();
break;
}
}
};
Camera.PictureCallback mCall = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
//decode the data obtained by the camera into a Bitmap
//display.setImageBitmap(photo);
Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(data, 0, data.length);
display.setImageBitmap(bitmapPicture);
Message.obtain(threadHandler, MainActivity.NEXT, "").sendToTarget();
//Log.v("MyActivity","Length: "+data.length);
}
};
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
Log.v("MyActivity", "Camera found");
cameraId = i;
break;
}
}
return cameraId;
}
@Override
protected void onPause() {
if (timer!=null){
timer.cancel(true);
}
releaseCamera();
super.onPause();
}
// I think Android Documentation recommends doing this in a separate
// task to avoid blocking main UI
private boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCamera();
camera = Camera.open(id);
qOpened = (camera != null);
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
return qOpened;
}
private void releaseCamera() {
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
}
例外
02-02 12:44:58.941: E/AndroidRuntime(2067): FATAL EXCEPTION: main
02-02 12:44:58.941: E/AndroidRuntime(2067): java.lang.RuntimeException: takePicture failed
02-02 12:44:58.941: E/AndroidRuntime(2067): at android.hardware.Camera.native_takePicture(Native Method)
02-02 12:44:58.941: E/AndroidRuntime(2067): at android.hardware.Camera.takePicture(Camera.java:1146)
02-02 12:44:58.941: E/AndroidRuntime(2067): at android.hardware.Camera.takePicture(Camera.java:1091)
02-02 12:44:58.941: E/AndroidRuntime(2067): at com.example.capturefindmyphone.MainActivity$1.handleMessage(MainActivity.java:80)
02-02 12:44:58.941: E/AndroidRuntime(2067): at android.os.Handler.dispatchMessage(Handler.java:99)
02-02 12:44:58.941: E/AndroidRuntime(2067): at android.os.Looper.loop(Looper.java:137)
02-02 12:44:58.941: E/AndroidRuntime(2067): at android.app.ActivityThread.main(ActivityThread.java:4960)
02-02 12:44:58.941: E/AndroidRuntime(2067): at java.lang.reflect.Method.invokeNative(Native Method)
02-02 12:44:58.941: E/AndroidRuntime(2067): at java.lang.reflect.Method.invoke(Method.java:511)
02-02 12:44:58.941: E/AndroidRuntime(2067): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
02-02 12:44:58.941: E/AndroidRuntime(2067): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
02-02 12:44:58.941: E/AndroidRuntime(2067): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:0)
它已经有一段时间了,我对此有点生疏,而且非常暧昧&#34; takePicture失败&#34;没有帮助。但这可能是因为预览表面尚未准备好吗?参见&#34; setPreviewDisplay&#34;的第二段。文档。
http://developer.android.com/reference/android/hardware/Camera.html#setPreviewDisplay(android.view.SurfaceHolder) public final void setPreviewDisplay(SurfaceHolder holder)
在API级别1中添加 设置要用于实时预览的Surface。预览需要表面或表面纹理,拍摄时需要预览。可以重新设置相同的表面而不会造成伤害。设置预览曲面将取消设置通过setPreviewTexture(SurfaceTexture)设置的任何预览曲面纹理。
调用此方法时,SurfaceHolder必须已包含曲面。如果您使用的是SurfaceView,则需要在调用setPreviewDisplay()或开始预览之前使用addCallback(SurfaceHolder.Callback)注册SurfaceHolder.Callback并等待surfaceCreated(SurfaceHolder)。