错误发生在CameraFragment
内 - 一个只包含FrameLayout(用于保存相机预览)和ImageButton(用于捕获图像)的片段。在我的片段中,我有一个PictureCallback:
private static Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
CameraFragment.DATA=data;
final int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_STORAGE
);
return;
}
saveImageToDevice();
}
};
我从HandlerThread获取了我的Camera实例:
private CameraHandlerThread mThread = null;
private static class CameraHandlerThread extends HandlerThread {
Handler mHandler = null;
private Camera handlerCamera;
CameraHandlerThread() {
super("CameraHandlerThread");
start();
mHandler = new Handler(getLooper());
}
synchronized void notifyCameraOpened() {
notify();
}
void openCamera() {
mHandler.post(new Runnable() {
@Override
public void run() {
handlerCamera = getCameraInstance();
notifyCameraOpened();
}
});
try {
wait();
}
catch (InterruptedException e) {
}
}
public Camera getCamera() {
return handlerCamera;
}
}
然后我在OnCreateView()中调用此方法(发生异常的地方):
private void launchCamera() {
newOpenCamera();
mPreview = new CameraPreview(getContext(), mCamera, activity);
mPreview.setCameraDisplayOrientation(activity, CAMERA_ID, mCamera);
preview = (FrameLayout) view.findViewById(R.id.tvCamera);
preview.addView(mPreview);
ivCaptureImage = (ImageView) view.findViewById(R.id.ivCaptureImage);
ivCaptureImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
}
其中newOpenCamera是:
private void newOpenCamera() {
if (mThread == null) {
mThread = new CameraHandlerThread();
}
synchronized (mThread) {
mThread.openCamera();
mCamera = mThread.getCamera();
}
}
我运行了调试器并且可以看到发生错误的行(launchCamera()中的mCamera.takePicture(...))被调用,但错误在PictureCallback之前被抛出。错误是:
E/UncaughtException: java.lang.RuntimeException: takePicture failed
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1523)
at android.hardware.Camera.takePicture(Camera.java:1468)
at com.myapp.myapp.camera.CameraFragment$2.onClick(CameraFragment.java:175)
at android.view.View.performClick(View.java:5697)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
05-28 17:09:22.600 1171-1171/com.myapp.myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.myapp, PID: 1171
java.lang.RuntimeException: takePicture failed
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1523)
at android.hardware.Camera.takePicture(Camera.java:1468)
at com.myapp.myapp.camera.CameraFragment$2.onClick(CameraFragment.java:175)
at android.view.View.performClick(View.java:5697)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
有谁知道什么可能是错的?正如您所看到的,每拍一张照片,我总会得到两个相同的错误。
任何帮助都非常感谢,欢呼。
编辑:
我已经设置了警卫来阻止单个触摸注册为多个,如下所述:java.lang.RuntimeException: takePicture failed
仍然没有运气
答案 0 :(得分:0)
答案 1 :(得分:0)
我认为您忘记在相机对象上调用startPreview()方法。 从官方文档:
6.Important:调用startPreview()开始更新预览曲面。必须先开始预览才能拍照。
https://developer.android.com/reference/android/hardware/Camera
答案 2 :(得分:0)
使用这种方式使用表面视图打开相机 Java代码
public class CameraOverlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
private File videoPath;
private ImageView imgCapture;
int camBackId;
String strVideoFolderPath;
private ProgressDialog progressDialog;
Camera.Parameters parameters;
public boolean hasFlash;
public boolean camRotation = false;
private RelativeLayout relativeLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_overlay);
relativeLayout = findViewById(R.id.control);
camBackId = Camera.CameraInfo.CAMERA_FACING_BACK;
hasFlash = this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
surfaceView = findViewById(R.id.surface);
progressDialog = new ProgressDialog(this);
progressDialog.setTitle(null);
progressDialog.setCancelable(false);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
strVideoFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
videoPath = new File(Environment.getExternalStorageDirectory() + "/sw/raw");
if (videoPath.exists()) {
if (videoPath.isDirectory()) {
if (videoPath.listFiles().length != 0) {
String[] children = videoPath.list();
for (int i = 0; i < children.length; i++) {
new File(videoPath, children[i]).delete();
}
}
}
}
if (!videoPath.exists()) {
videoPath.mkdirs();
}
imgCapture = findViewById(R.id.img_capture);
imgCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (camera != null) {
if (previewing) {
System.gc();
try {
capturePhoto();
} catch (Exception e) {
Log.v("ERRORR", e.getMessage());
e.printStackTrace();
}
}
}
}
});
}
public void capturePhoto() throws Exception {
camera.takePicture(null, null, myPictureCallback_JPG);
}
@Override
protected void onResume() {
super.onResume();
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
}
Camera.PictureCallback myPictureCallback_JPG = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
FileOutputStream outStream = null;
//camera.startPreview();
try {
Date date = new Date();
String filename = "/rec" + date.toString().replace(" ", "_").replace(":", "_") + ".jpg";
filename = filename.replace("+", "");
File file = new File(Environment.getExternalStorageDirectory() + "/Switch It");
if (!file.exists())
file.mkdirs();
outStream = new FileOutputStream(file + filename);
outStream.write(arg0);
outStream.close();
Log.v("File_Path", file.getAbsolutePath());
Intent returnIntent = new Intent();
returnIntent.putExtra("img_capture", file.getAbsolutePath() + filename);
setResult(Activity.RESULT_OK, returnIntent);
finish();
} catch (FileNotFoundException e) {
Log.e("ERROR 1", e.getMessage());
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Log.e("ERROR 2", e.getMessage());
} finally {
}
}
};
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
parameters = camera.getParameters();
if (getPackageManager().hasSystemFeature("android.hardware.camera.autofocus")) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
camera.startPreview();
if (hasFlash) {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
camera.setParameters(parameters);
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
if (android.os.Build.VERSION.SDK_INT > 7) {
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if (display.getRotation() == Surface.ROTATION_0) {
camera.setDisplayOrientation(90);
camRotation = true;
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
}
XML代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/control"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/surface"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/img_capture"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:src="@drawable/ic_lens_black_24dp" />
</RelativeLayout>
答案 3 :(得分:0)
检查是否已为该特定应用程序设置了使用相机的权限。转到设置 - &gt;应用 - &gt; “您的应用名称” - &gt;权限 - &gt;打开相机的权限。 还要确保已在manifest.xml文件中设置了权限。它被命名为:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
查看此链接了解更多详情:
答案 4 :(得分:0)
尝试这个适用于我,并检查清单文件中给出的权限。
import javax.swing.*;
import java.util.List;
public class main {
public static void main(String[] args) {
JFrame frame = new JFrame();
JTextField textField = new JTextField();
List<JButton> list = Buttons.generateButtons(frame);
String displayOnTextField = Buttons.displayOnTextField(list,textField);
frame.setSize(400,600);
textField.setBounds(150,40,150,30);
frame.add(textField);
frame.setLayout(null);
frame.setVisible(true);
}
}