android – Camera2 Api..java.lang.IllegalArgumentException:Surface没有有效的原生Surface

前端之家收集整理的这篇文章主要介绍了android – Camera2 Api..java.lang.IllegalArgumentException:Surface没有有效的原生Surface前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我试图将Camera2 api集成到我的app.Its工作正常,最初捕获图像.但是当我第二次拍摄时预览没有来.我在genymotion nexus 5模拟器中测试了它.与所有例子结合.预览是不是第二次抢购.也得到了这个错误. java.lang.IllegalArgumentException:Surface没有有效的原生Surface …

我按照这两个代码
http://inducesmile.com/android/android-camera2-api-example-tutorial/?cid=519
Github-Camera2Master.Please帮助任何人解决错误,并提供一些链接,以获取有关相机2 api的更详细说明

  1. package com.example.cameraapi;
  2. import android.Manifest;
  3. import android.content.Context;
  4. import android.content.pm.PackageManager;
  5. import android.graphics.ImageFormat;
  6. import android.graphics.SurfaceTexture;
  7. import android.hardware.camera2.CameraAccessException;
  8. import android.hardware.camera2.CameraCaptureSession;
  9. import android.hardware.camera2.CameraCharacteristics;
  10. import android.hardware.camera2.CameraDevice;
  11. import android.hardware.camera2.CameraManager;
  12. import android.hardware.camera2.CameraMetadata;
  13. import android.hardware.camera2.CaptureRequest;
  14. import android.hardware.camera2.TotalCaptureResult;
  15. import android.hardware.camera2.params.StreamConfigurationMap;
  16. import android.media.Image;
  17. import android.media.ImageReader;
  18. import android.os.Bundle;
  19. import android.os.Environment;
  20. import android.os.Handler;
  21. import android.os.HandlerThread;
  22. import android.support.annotation.NonNull;
  23. import android.support.v4.app.ActivityCompat;
  24. import android.support.v7.app.AppCompatActivity;
  25. import android.util.Log;
  26. import android.util.Size;
  27. import android.util.SparseIntArray;
  28. import android.view.Surface;
  29. import android.view.TextureView;
  30. import android.view.View;
  31. import android.widget.Button;
  32. import android.widget.Toast;
  33. import java.io.File;
  34. import java.io.FileNotFoundException;
  35. import java.io.FileOutputStream;
  36. import java.io.IOException;
  37. import java.io.OutputStream;
  38. import java.nio.ByteBuffer;
  39. import java.util.ArrayList;
  40. import java.util.Arrays;
  41. import java.util.List;
  42. public class AndroidCameraApi extends AppCompatActivity {
  43. private static final String TAG = "AndroidCameraApi";
  44. private Button takePictureButton;
  45. private TextureView textureView;
  46. private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
  47. static {
  48. ORIENTATIONS.append(Surface.ROTATION_0,90);
  49. ORIENTATIONS.append(Surface.ROTATION_90,0);
  50. ORIENTATIONS.append(Surface.ROTATION_180,270);
  51. ORIENTATIONS.append(Surface.ROTATION_270,180);
  52. }
  53. private String cameraId;
  54. protected CameraDevice cameraDevice;
  55. protected CameraCaptureSession cameraCaptureSessions;
  56. protected CaptureRequest captureRequest;
  57. protected CaptureRequest.Builder captureRequestBuilder;
  58. private Size imageDimension;
  59. private ImageReader imageReader;
  60. private File file;
  61. private static final int REQUEST_CAMERA_PERMISSION = 200;
  62. private boolean mFlashSupported;
  63. private Handler mBackgroundHandler;
  64. private HandlerThread mBackgroundThread;
  65. @Override
  66. protected void onCreate(Bundle savedInstanceState) {
  67. super.onCreate(savedInstanceState);
  68. setContentView(R.layout.activity_camera);
  69. textureView = (TextureView) findViewById(R.id.textureView);
  70. assert textureView != null;
  71. textureView.setSurfaceTextureListener(textureListener);
  72. takePictureButton = (Button) findViewById(R.id.btn_takepicture);
  73. assert takePictureButton != null;
  74. takePictureButton.setOnClickListener(new View.OnClickListener() {
  75. @Override
  76. public void onClick(View v) {
  77. takePicture();
  78. }
  79. });
  80. }
  81. TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
  82. @Override
  83. public void onSurfaceTextureAvailable(SurfaceTexture surface,int width,int height) {
  84. //open your camera here
  85. openCamera();
  86. }
  87. @Override
  88. public void onSurfaceTextureSizeChanged(SurfaceTexture surface,int height) {
  89. // Transform you image captured size according to the surface width and height
  90. }
  91. @Override
  92. public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
  93. return false;
  94. }
  95. @Override
  96. public void onSurfaceTextureUpdated(SurfaceTexture surface) {
  97. }
  98. };
  99. private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
  100. @Override
  101. public void onOpened(CameraDevice camera) {
  102. //This is called when the camera is open
  103. Log.e(TAG,"onOpened");
  104. cameraDevice = camera;
  105. createCameraPreview();
  106. }
  107. @Override
  108. public void onDisconnected(CameraDevice camera) {
  109. cameraDevice.close();
  110. }
  111. @Override
  112. public void onError(CameraDevice camera,int error) {
  113. if(cameraDevice!=null)
  114. cameraDevice.close();
  115. cameraDevice = null;
  116. }
  117. };
  118. final CameraCaptureSession.CaptureCallback captureCallbackListener = new CameraCaptureSession.CaptureCallback() {
  119. @Override
  120. public void onCaptureCompleted(CameraCaptureSession session,CaptureRequest request,TotalCaptureResult result) {
  121. super.onCaptureCompleted(session,request,result);
  122. // Toast.makeText(AndroidCameraApi.this,"Saved:" + file,Toast.LENGTH_SHORT).show();
  123. createCameraPreview();
  124. }
  125. };
  126. protected void startBackgroundThread() {
  127. mBackgroundThread = new HandlerThread("Camera Background");
  128. mBackgroundThread.start();
  129. mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
  130. }
  131. protected void stopBackgroundThread() {
  132. mBackgroundThread.quitSafely();
  133. try {
  134. mBackgroundThread.join();
  135. mBackgroundThread = null;
  136. mBackgroundHandler = null;
  137. } catch (InterruptedException e) {
  138. e.printStackTrace();
  139. }
  140. }
  141. protected void takePicture() {
  142. if(null == cameraDevice) {
  143. Log.e(TAG,"cameraDevice is null");
  144. return;
  145. }
  146. CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
  147. try {
  148. CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
  149. Size[] jpegSizes = null;
  150. if (characteristics != null) {
  151. jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
  152. }
  153. int width = 640;
  154. int height = 480;
  155. if (jpegSizes != null && 0 < jpegSizes.length) {
  156. width = jpegSizes[0].getWidth();
  157. height = jpegSizes[0].getHeight();
  158. }
  159. ImageReader reader = ImageReader.newInstance(width,height,ImageFormat.JPEG,1);
  160. ListMetadata.CONTROL_MODE_AUTO);
  161. // Orientation
  162. int rotation = getWindowManager().getDefaultDisplay().getRotation();
  163. captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
  164. final File file = new File(Environment.getExternalStorageDirectory()+"/pic.jpg");
  165. ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
  166. @Override
  167. public void onImageAvailable(ImageReader reader) {
  168. Image image = null;
  169. try {
  170. image = reader.acquireLatestImage();
  171. ByteBuffer buffer = image.getPlanes()[0].getBuffer();
  172. byte[] bytes = new byte[buffer.capacity()];
  173. buffer.get(bytes);
  174. save(bytes);
  175. } catch (FileNotFoundException e) {
  176. e.printStackTrace();
  177. } catch (IOException e) {
  178. e.printStackTrace();
  179. } finally {
  180. if (image != null) {
  181. image.close();
  182. }
  183. }
  184. }
  185. private void save(byte[] bytes) throws IOException {
  186. OutputStream output = null;
  187. try {
  188. output = new FileOutputStream(file);
  189. output.write(bytes);
  190. } finally {
  191. if (null != output) {
  192. output.close();
  193. }
  194. }
  195. }
  196. };
  197. reader.setOnImageAvailableListener(readerListener,mBackgroundHandler);
  198. final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
  199. @Override
  200. public void onCaptureCompleted(CameraCaptureSession session,TotalCaptureResult result) {
  201. super.onCaptureCompleted(session,result);
  202. // Toast.makeText(AndroidCameraApi.this,Toast.LENGTH_SHORT).show();
  203. createCameraPreview();
  204. }
  205. };
  206. cameraDevice.createCaptureSession(outputSurfaces,new CameraCaptureSession.StateCallback() {
  207. @Override
  208. public void onConfigured(CameraCaptureSession session) {
  209. try {
  210. session.capture(captureBuilder.build(),captureListener,mBackgroundHandler);
  211. } catch (CameraAccessException e) {
  212. e.printStackTrace();
  213. }
  214. }
  215. @Override
  216. public void onConfigureFailed(CameraCaptureSession session) {
  217. }
  218. },mBackgroundHandler);
  219. } catch (CameraAccessException e) {
  220. e.printStackTrace();
  221. }
  222. }
  223. protected void createCameraPreview() {
  224. try {
  225. SurfaceTexture texture = textureView.getSurfaceTexture();
  226. assert texture != null;
  227. texture.setDefaultBufferSize(imageDimension.getWidth(),imageDimension.getHeight());
  228. Surface surface = new Surface(texture);
  229. captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
  230. captureRequestBuilder.addTarget(surface);
  231. cameraDevice.createCaptureSession(Arrays.asList(surface),new CameraCaptureSession.StateCallback(){
  232. @Override
  233. public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
  234. //The camera is already closed
  235. if (null == cameraDevice) {
  236. return;
  237. }
  238. // When the session is ready,we start displaying the preview.
  239. cameraCaptureSessions = cameraCaptureSession;
  240. updatePreview();
  241. }
  242. @Override
  243. public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
  244. Toast.makeText(AndroidCameraApi.this,"Configuration change",Toast.LENGTH_SHORT).show();
  245. }
  246. },null);
  247. } catch (CameraAccessException e) {
  248. e.printStackTrace();
  249. }
  250. }
  251. private void openCamera() {
  252. CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
  253. Log.e(TAG,"is camera open");
  254. try {
  255. cameraId = manager.getCameraIdList()[0];
  256. CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
  257. StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
  258. assert map != null;
  259. imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
  260. // Add permission for camera and let user grant the permission
  261. if (ActivityCompat.checkSelfPermission(this,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
  262. ActivityCompat.requestPermissions(AndroidCameraApi.this,new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CAMERA_PERMISSION);
  263. return;
  264. }
  265. manager.openCamera(cameraId,stateCallback,null);
  266. } catch (CameraAccessException e) {
  267. e.printStackTrace();
  268. }
  269. Log.e(TAG,"openCamera X");
  270. }
  271. protected void updatePreview() {
  272. if(null == cameraDevice) {
  273. Log.e(TAG,"updatePreview error,return");
  274. }
  275. captureRequestBuilder.set(CaptureRequest.CONTROL_MODE,CameraMetadata.CONTROL_MODE_AUTO);
  276. try {
  277. cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);
  278. } catch (CameraAccessException e) {
  279. e.printStackTrace();
  280. }
  281. }
  282. private void closeCamera() {
  283. if (null != cameraDevice) {
  284. cameraDevice.close();
  285. cameraDevice = null;
  286. }
  287. if (null != imageReader) {
  288. imageReader.close();
  289. imageReader = null;
  290. }
  291. }
  292. @Override
  293. public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {
  294. if (requestCode == REQUEST_CAMERA_PERMISSION) {
  295. if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
  296. // close the app
  297. Toast.makeText(AndroidCameraApi.this,"Sorry!!!,you can't use this app without granting permission",Toast.LENGTH_LONG).show();
  298. finish();
  299. }
  300. }
  301. }
  302. @Override
  303. protected void onResume() {
  304. super.onResume();
  305. Log.e(TAG,"onResume");
  306. startBackgroundThread();
  307. if (textureView.isAvailable()) {
  308. openCamera();
  309. } else {
  310. textureView.setSurfaceTextureListener(textureListener);
  311. }
  312. }
  313. @Override
  314. protected void onPause() {
  315. Log.e(TAG,"onPause");
  316. //closeCamera();
  317. stopBackgroundThread();
  318. super.onPause();
  319. }
  320. }

当我开始拍摄更多图像时,我得到的错误如下所示.在第二张图像本身之后没有更多.

  1. 09-30 07:36:43.199 6252-6305/com.example.cameraapi E/Legacy-CameraDevice-JNI: LegacyCameraDevice_nativeGetSurfaceId: Could not retrieve native Surface from surface.
  2. 09-30 07:36:43.199 6252-6305/com.example.cameraapi E/AndroidRuntime: FATAL EXCEPTION: Thread-275
  3. Process: com.example.cameraapi,PID: 6252
  4. java.lang.IllegalArgumentException: Surface had no valid native Surface.
  5. at android.hardware.camera2.legacy.LegacyCameraDevice.nativeGetSurfaceId(Native Method)
  6. at android.hardware.camera2.legacy.LegacyCameraDevice.getSurfaceId(LegacyCameraDevice.java:658)
  7. at android.hardware.camera2.legacy.LegacyCameraDevice.containsSurfaceId(LegacyCameraDevice.java:678)
  8. at android.hardware.camera2.legacy.RequestThreadManager$2.onPictureTaken(RequestThreadManager.java:220)
  9. at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1092)
  10. at android.os.Handler.dispatchMessage(Handler.java:102)
  11. at android.os.Looper.loop(Looper.java:148)
  12. at android.hardware.camera2.legacy.CameraDeviceUserShim$CameraLooper.run(CameraDeviceUserShim.java:136)
  13. at java.lang.Thread.run(Thread.java:818)
  14. 09-30 07:36:43.373 6252-6252/com.example.cameraapi E/AndroidCameraApi: onPause
  15. 09-30 07:36:43.463 6252-6292/com.example.cameraapi E/Surface: getSlotFromBufferLocked: unknown buffer: 0xe05090e0
  16. 09-30 07:36:43.475 6252-6292/com.example.cameraapi D/OpenGLRenderer: endAllStagingAnimators on 0xe8b85100 (RippleDrawable) with handle 0xdf9d43d0
  17. 09-30 07:36:47.201 6252-6313/com.example.cameraapi E/RequestThread-0: Hit timeout for jpeg callback!
  18. 09-30 07:36:47.202 6252-6313/com.example.cameraapi I/CameraDeviceState: Legacy camera service transitioning to state IDLE
  19. 09-30 07:36:47.203 6252-6252/com.example.cameraapi W/MessageQueue: Handler (android.os.Handler) {ef17f10} sending message to a Handler on a dead thread
  20. java.lang.IllegalStateException: Handler (android.os.Handler) {ef17f10} sending message to a Handler on a dead thread
  21. at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
  22. at android.os.Handler.enqueueMessage(Handler.java:631)
  23. at android.os.Handler.sendMessageAtTime(Handler.java:600)
  24. at android.os.Handler.sendMessageDelayed(Handler.java:570)
  25. at android.os.Handler.post(Handler.java:326)
  26. at android.hardware.camera2.dispatch.HandlerDispatcher.dispatch(HandlerDispatcher.java:61)
  27. at android.hardware.camera2.dispatch.MethodNameInvoker.invoke(MethodNameInvoker.java:88)
  28. at android.hardware.camera2.dispatch.DuckTypingDispatcher.dispatch(DuckTypingDispatcher.java:53)
  29. at android.hardware.camera2.dispatch.ArgumentReplacingDispatcher.dispatch(ArgumentReplacingDispatcher.java:74)
  30. at android.hardware.camera2.dispatch.BroadcastDispatcher.dispatch(BroadcastDispatcher.java:54)
  31. at android.hardware.camera2.dispatch.MethodNameInvoker.invoke(MethodNameInvoker.java:88)
  32. at android.hardware.camera2.impl.CallbackProxies$DeviceCaptureCallbackProxy.onCaptureCompleted(CallbackProxies.java:121)
  33. at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$4.run(CameraDeviceImpl.java:1828)
  34. at android.os.Handler.handleCallback(Handler.java:739)
  35. at android.os.Handler.dispatchMessage(Handler.java:95)
  36. at android.os.Looper.loop(Looper.java:148)
  37. at android.app.ActivityThread.main(ActivityThread.java:5417)
  38. at java.lang.reflect.Method.invoke(Native Method)
  39. at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
  40. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
  41. 09-30 07:36:47.204 6252-6252/com.example.cameraapi W/MessageQueue: Handler (android.os.Handler) {ef17f10} sending message to a Handler on a dead thread
  42. java.lang.IllegalStateException: Handler (android.os.Handler) {ef17f10} sending message to a Handler on a dead thread
  43. at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
  44. at android.os.Handler.enqueueMessage(Handler.java:631)
  45. at android.os.Handler.sendMessageAtTime(Handler.java:600)
  46. at android.os.Handler.sendMessageDelayed(Handler.java:570)
  47. at android.os.Handler.post(Handler.java:326)
  48. at android.hardware.camera2.dispatch.HandlerDispatcher.dispatch(HandlerDispatcher.java:61)
  49. at android.hardware.camera2.dispatch.MethodNameInvoker.invoke(MethodNameInvoker.java:88)
  50. at android.hardware.camera2.dispatch.DuckTypingDispatcher.dispatch(DuckTypingDispatcher.java:53)
  51. at android.hardware.camera2.dispatch.ArgumentReplacingDispatcher.dispatch(ArgumentReplacingDispatcher.java:74)
  52. at android.hardware.camera2.dispatch.BroadcastDispatcher.dispatch(BroadcastDispatcher.java:54)
  53. at android.hardware.camera2.dispatch.MethodNameInvoker.invoke(MethodNameInvoker.java:88)
  54. at android.hardware.camera2.impl.CallbackProxies$DeviceCaptureCallbackProxy.onCaptureSequenceCompleted(CallbackProxies.java:133)
  55. at android.hardware.camera2.impl.CameraDeviceImpl$10.run(CameraDeviceImpl.java:1588)
  56. at android.os.Handler.handleCallback(Handler.java:739)
  57. at android.os.Handler.dispatchMessage(Handler.java:95)
  58. at android.os.Looper.loop(Looper.java:148)
  59. at android.app.ActivityThread.main(ActivityThread.java:5417)
  60. at java.lang.reflect.Method.invoke(Native Method)
  61. at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
  62. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
  63. [ 09-30 07:36:48.448 6252: 6257 D/ ]
  64. HostConnection::get() New Host Connection established 0xe9952950,tid 6257
最佳答案
我以前见过这个问题,因为Camera使用的线程不再存在.调试Camera API,您将看到它使用Handlers来调用必要的函数.在死线程上向Handler发送消息的罪魁祸首就在这里:

  1. @Override
  2. protected void onPause() {
  3. Log.e(TAG,"onPause");
  4. //closeCamera();
  5. stopBackgroundThread();
  6. super.onPause();
  7. }

您的onPause()正在杀死CameraAPI正在使用的线程,该线程导致该错误消息.这不是真正的问题,而是LegacyCameraDevice_nativeGetSurfaceId:无法从表面检索本机Surface.如果表面没有配置到正确的参数,Camera2 API会抱怨很多.由于您正在使用该示例,您可能应该像链接的示例一样初始化和配置TextureView.我知道他们扩展了类并提供了一个帮助方法来配置,可能会解决这个问题.

作为旁注,你应该在做自己的事情之前调用super.

猜你在找的Android相关文章