作为一个学习练习,我正在编写一个安全应用程序,当发生任意事件时,需要打开相机,拍照并关闭相机,而不必担心闪光,对焦或显示预习.我跟着在线演示并制作了一个可以拍照的工作应用程序,但它使用预览和所有这些.所以我开始努力让它在没有预览的情况下工作.无论如何,我不断得到’takePicture Failed’例外,我没有任何世俗的想法.我希望有更多使用Camera API经验的人可以看看并指出我的解决方案.以下是我的相关文件.我正在使用最新的Android Studio并在galaxy S4上进行测试.
[MainActivity.java]
package com.g5digital.cam2;import androID.content.pm.PackageManager;import androID.harDWare.Camera;import androID.support.v7.app.ActionBaractivity;import androID.os.Bundle;import androID.util.Log;import androID.vIEw.Menu;import androID.vIEw.MenuItem;import androID.vIEw.VIEw;import androID.Widget.button;import androID.Widget.linearLayout;import androID.Widget.Toast;import java.io.IOException;public class MainActivity extends ActionBaractivity implements VIEw.OnClickListener { private static final String TAG = "MainActivity"; private button button; private int cameraID; private Camera camera; private CameraPrevIEw camPrevIEw; private linearLayout container; private Camera.Parameters camParms; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); container = (linearLayout)findVIEwByID(R.ID.container); button = (button)findVIEwByID(R.ID.button); button.setonClickListener(this); } @OverrIDe public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @OverrIDe public boolean onoptionsItemSelected(MenuItem item) { int ID = item.getItemID(); if (ID == R.ID.action_settings) { return true; } return super.onoptionsItemSelected(item); } @OverrIDe public voID onClick(VIEw vIEw) { openCamera(); try { if (camera != null) { PhotoHandler ph = new PhotoHandler(this, camera); camera.takePicture(null, null, ph); // Commented until takePicture() works /*(new Handler()).postDelayed(new Runnable() { @OverrIDe public voID run() { MainActivity.this.closeCamera(); } }, 1000);*/ } } catch (Exception e) { closeCamera(); Log.d(TAG, e.getMessage()); e.printstacktrace(); } } private voID openCamera() { // do we have a camera? if (!getPackageManager() .hasSystemFeature(PackageManager.FEATURE_CAMERA)) { Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG) .show(); } else { closeCamera(); cameraID = findFrontFacingCameraID(); if (cameraID < 0) { Toast.makeText(this, "No front facing camera found.", Toast.LENGTH_LONG).show(); } else { camera = Camera.open(cameraID); try { setCamParms(); setCamPrevIEw(); camera.startPrevIEw(); } catch (Exception e) { closeCamera(); e.printstacktrace(); finish(); return; } } } } private voID closeCamera() { if (camera != null) { camera.release(); camera = null; } } private int findFrontFacingCameraID() { int camera_ID = -1; // Search for the front facing camera int numberOfCameras = Camera.getNumberOfCameras(); for (int i = 0; i < numberOfCameras; i++) { Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(i, info); if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { Log.d(TAG, "Camera found"); camera_ID = i; break; } } return camera_ID; } private voID setCamParms() { if (camParms == null && camera != null) { camParms = camera.getParameters(); camParms.setFlashMode("Off"); } if (camera != null) { camera.setParameters(camParms); camera.setdisplayOrIEntation(90); } } private voID setCamPrevIEw() throws IOException { if (camPrevIEw == null && camera != null) { camPrevIEw = new CameraPrevIEw(this, camera); } if (camera != null) { camera.setPrevIEwdisplay(camPrevIEw.getHolder()); } }}
[CameraPrevIEw.java]
package com.g5digital.cam2;import androID.content.Context;import androID.harDWare.Camera;import androID.util.Log;import androID.vIEw.SurfaceHolder;import androID.vIEw.SurfaceVIEw;import java.io.IOException;public class CameraPrevIEw extends SurfaceVIEw implements SurfaceHolder.Callback { private Context context; private Camera camera; private SurfaceHolder holder; private static final String TAG = "CameraPrevIEw"; public CameraPrevIEw(Context c, Camera cam) { super(c); context = c; camera = cam; holder = getHolder(); holder.addCallback(this); } @OverrIDe public voID surfaceCreated(SurfaceHolder surfaceHolder) { try { camera.setPrevIEwdisplay(holder); camera.startPrevIEw(); } catch (IOException e) { Log.d(TAG, "Error setting camera prevIEw: " + e.getMessage()); } catch (Exception e) { // Probably getting "called after release()" message e.printstacktrace(); } } @OverrIDe public voID surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) { // If your prevIEw can change or rotate, take care of those events here. // Make sure to stop the prevIEw before resizing or reformatting it. if (holder.getSurface() == null){ // prevIEw surface does not exist return; } // stop prevIEw before making changes try { camera.stopPrevIEw(); } catch (Exception e){ // ignore: trIEd to stop a non-existent prevIEw } // set prevIEw size and make any resize, rotate or // reformatting changes here // start prevIEw with new settings try { camera.setPrevIEwdisplay(holder); camera.startPrevIEw(); } catch (Exception e){ Log.d(TAG, "Error starting camera prevIEw: " + e.getMessage()); } } @OverrIDe public voID surfaceDestroyed(SurfaceHolder surfaceHolder) { // }}
[PhotoHandler.java]
package com.g5digital.cam2;import androID.content.Context;import androID.graphics.Bitmap;import androID.graphics.BitmapFactory;import androID.graphics.Matrix;import androID.harDWare.Camera;import androID.os.Environment;import androID.util.Log;import androID.Widget.Toast;import java.io.file;import java.io.fileOutputStream;import java.text.SimpleDateFormat;import java.util.Date;public class PhotoHandler implements Camera.PictureCallback { private final Context context; private final Camera camera; public PhotoHandler(Context context, Camera c) { this.context = context; this.camera = c; } @OverrIDe public voID onPictureTaken(byte[] bytes, Camera cam) { Log.i("PhotoHandler", "Picture taken!"); file picturefileDir = getDir(); if (!picturefileDir.exists() && !picturefileDir.mkdirs()) { Log.d("PhotoHandler", "Can't create directory to save image."); Toast.makeText(context, "Can't create directory to save image.", Toast.LENGTH_LONG).show(); return; } Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); int wIDth = bmp.getWIDth(); int height = bmp.getHeight(); Matrix matrix = new Matrix(); matrix.postRotate(270); Bitmap rotatedBitmap = Bitmap.createBitmap(bmp, 0, 0, wIDth, height, matrix, true); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String date = dateFormat.format(new Date()); String photofile = "Picture_" + date + ".jpg"; String filename = picturefileDir.getPath() + file.separator + photofile; file picturefile = new file(filename); try { fileOutputStream fos = new fileOutputStream(picturefile); boolean result = rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); //fos.write(bytes); fos.close(); if (result) { Toast.makeText(context, "New Image saved:" + photofile, Toast.LENGTH_LONG).show(); } else { Toast.makeText(context, "Couldn't save image:" + photofile, Toast.LENGTH_LONG).show(); } camera.startPrevIEw(); } catch (Exception error) { Log.d("PhotoHandler", "file" + filename + "not saved: " + error.getMessage()); Toast.makeText(context, "Image Could not be saved.", Toast.LENGTH_LONG).show(); } } private file getDir() { file sdDir = Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); return new file(sdDir, "CameraAPIDemo"); }}
[AndroIDManifest.xml中]
<?xml version="1.0" enCoding="utf-8"?><manifest xmlns:androID="http://schemas.androID.com/apk/res/androID" package="com.g5digital.cam2" > <uses-permission androID:name="androID.permission.CAMERA" /> <uses-permission androID:name="androID.permission.FLASHliGHT" /> <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE" /> <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature androID:name="androID.harDWare.camera" /> <uses-feature androID:name="androID.harDWare.camera.autofocus" /> <application androID:allowBackup="true" androID:icon="@drawable/ic_launcher" androID:label="@string/app_name" androID:theme="@style/Apptheme" > <activity androID:name="com.g5digital.cam2.MainActivity" androID:label="@string/app_name" androID:screenorIEntation="portrait"> <intent-filter> <action androID:name="androID.intent.action.MAIN" /> <category androID:name="androID.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
[activity_main.xml中]
<linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:tools="http://schemas.androID.com/tools" androID:ID="@+ID/container" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical" tools:context="com.g5digital.cam2.MainActivity" tools:ignore="MergeRootFrame"> <button androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="@string/click" androID:ID="@+ID/button" /></linearLayout>
[LogCat输出]
01-29 14:55:45.826 5853-5853/com.g5digital.cam2 D/MainActivity﹕ takePicture Failed01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ java.lang.RuntimeException: takePicture Failed01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.harDWare.Camera.native_takePicture(Native Method)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.harDWare.Camera.takePicture(Camera.java:1194)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.harDWare.Camera.takePicture(Camera.java:1139)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at com.g5digital.cam2.MainActivity.onClick(MainActivity.java:66)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.vIEw.VIEw.performClick(VIEw.java:4475)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.vIEw.VIEw$PerformClick.run(VIEw.java:18786)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.os.Handler.handleCallback(Handler.java:730)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.os.Handler.dispatchMessage(Handler.java:92)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.os.Looper.loop(Looper.java:137)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at androID.app.ActivityThread.main(ActivityThread.java:5419)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:525)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:1003)01-29 14:55:45.836 5853-5853/com.g5digital.cam2 W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
解决方法:
不,拍照必须显示预览.有技巧的人发明了很多解决方法,例如, Take Picture without preview Android,
Android: Is it possible to take a picture with the camera from a service with no UI,How to use Camera to take picture in a background Service on Android? ……
但请记住,要求不是出于技术要求,而是出于隐私目的.系统继续发展并防范新发现的变通方法.
也许在S4上隐藏预览的最强大的方法是使用SurfaceTexture,但是不可见地显示它,例如转移了视口.
总结以上是内存溢出为你收集整理的java – Android Camera.takePicture失败全部内容,希望文章能够帮你解决java – Android Camera.takePicture失败所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)