- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
作为一个学习练习,我正在编写一个安全应用程序,当任意事件发生时,需要打开相机、拍照并关闭相机,而不用担心闪光灯、对焦、或显示预览。我跟随在线演示并制作了一个可以拍照的应用程序,但它使用预览等等。所以我开始努力让它在没有预览的情况下工作。不管怎样,我一直收到“拍照失败”的异常,我不知道为什么。我希望对 Camera API 有更多经验的人可以看看并指出解决方案的方向。以下是我的相关文件。我正在使用最新的 Android Studio 并在 Galaxy S4 上进行测试。
[主 Activity .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) {
//
}
}
[照片处理器.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 failed
01-29 14:55:45.826 5853-5853/com.g5digital.cam2 W/System.err﹕ java.lang.RuntimeException: takePicture failed
01-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,但不可见地显示它,例如移出视口(viewport)。
关于java - Android Camera.takePicture 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21441484/
我在 Android 中使用相机时遇到问题。 在 API 25 Nougat 7.1.1 SDK 上进行开发。最小目标 SDK 设置为 15。 每次调用时都会抛出错误: Camera camera =
在我尝试过的所有手机上,包括带有 API 2.3.7 和 4.0 的 Galaxy Nexus,在调用 takePicture 方法后表面 View 更改为拍摄的图像,即“图像查看”。 我已经在这些平
我正在尝试在 Flutter 中的相机预览上显示 CustomPaint 元素。现在,CustomPaint 元素显示在相机预览下方。我正在使用 Flutter camera plugin显示相机预览
我有一个自定义相机应用程序,它在 SurfaceView 上预览相机视频输出并尝试拍照,照片应该由“xzing”扫描仪 API 处理以解码图像中的任何条形码。 我的应用程序预览正确并且没有抛出任何错误
我已经实现了使用 Android MediaRecorder 在后台录制音频,如果录音正在进行并且用户打开了 native 摄像头来录制视频,它会提供 Camera Error "Can't Conn
我在浏览相机脚本时遇到了声明术语 new Camera camera; 我想知道这是做什么的。它是在创建一个实例吗?让我感到困惑的是脚本已经附加到 Inspector 中的相机对象。那么为什么需要创建
我使用了我的 Fabric 服务,并在大多数运行我的应用程序的设备上发现了这个错误。 错误是这样的: Fatal Exception: java.lang.NullPointerException A
private static final int SENSOR_ORIENTATION_DEFAULT_DEGREES = 90; private static final int SENSOR_OR
我正在开发一个基本的自定义相机应用这些是我的依赖 // CameraX core library dependency implementation "androidx.camera:camera-c
我正在为索尼相机制作一个跟焦应用程序。我的应用程序需要能够设置焦点标记并调用它们。有很多功能可以在 Sony Camera API 上进行自动对焦,但我希望能够手动将焦点设置为给定的绝对值。有没有办法
我已经浏览了 Nest 开发人员网站,但找不到与相机相关的任何内容。我可以找到很多关于恒温器和烟雾/一氧化碳警报器的重要信息,但没有关于相机的信息。 特别是,我正在寻找如何获取视频 URL、如何获取/
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 8 年前。 Improve t
我使用 create-react-native-app (CRNA) 创建了一个 RN 项目。我想使用expo提供的Camera API。为此,我只是复制了此处的示例 https://docs.exp
我想让我的相机跟随移动实体的第一人称视角。我不相信 trackedEntity 将适用于此用例,因为我不想查看实体,但我想查看 从它。我还希望用户能够使用鼠标相对于移动实体转动相机(例如,从移动平面的
我有一个跟进问题 Android Camera Server Died and Camera ERROR 100 我的代码中出现了类似的错误。这个错误出现在我们随机运行许多应用程序的自动化测试中。很长
我正在尝试实现与 Facebook 或 Instagram 相同的功能: 即时预览相机拍摄的图像 此时,调用此函数时,我的拍摄已正确拍摄: takePicture = async function()
我想给 React native Camera 添加水印。每当我点击/拍摄图像时,应该保存带有水印的图像。 最佳答案 我用了react-native-image-marker它对我有用。 关于reac
虽然索尼向客户挑逗新相机型号(UMC-R10C、UMC-S3C)并提到 API 访问和 USB 连接(而不是 wifi),但索尼相机远程 API 目前只提到 wifi。有没有关于如何使用这些即将推出的
我正在尝试使用以下代码在我的 xamarin android 应用程序中使用相机功能。 Intent intent = new Intent(MediaStore.ActionImageCapture
我构建了一个人脸检测应用程序,我从 onPreviewFrame 获取帧,进行人脸检测,然后在 surfaceView 上方的 Canvas 上绘制一个圆圈。问题是当 Camera.StartPrev
我是一名优秀的程序员,十分优秀!