Articles of android camera

Android 6.0 RuntimeException:无法连接到摄像头服务

我的应用程序在Nexus5(Android6.0)中运行时出错。 错误是 java.lang.RuntimeException:无法连接到摄像头服务 我已经将权限添加到AndroidManifest.xml中。 但该应用程序可以使用另一部手机(Android5.1)和genymotion AVD(Android 4.0)。 关键代码如下 @Override public void onResume() { super.onResume(); try { mCamera = Camera.open(); }catch (Exception e){ Log.e(TAG,”open camera failed”,e); } }

将相机预览适合大于显示器的SurfaceView

我有一个Android应用程序需要全屏显示相机预览,无论getSupportedPreviewSizes()给出的预览大小没有失真。 我希望这会在高度或宽度上裁剪一些预览,但这并不关心我。 我之所以这样做是因为某些安卓摄像头(例如三星Galaxy SII前置摄像头)不会返回任何与显示器具有相同宽高比的预览,因此需要进行拉伸和剪裁。 是否可以将相机预览完全增加到大于显示尺寸的视图? 通过简单地将曲面视图的布局参数设置为match_parent,可以使SurfaceView大于返回的预览像素尺寸,但这会导致某些方向的失真,并且只有在预览填充显示之前才可能。 这似乎表明在显示器外部进行预览是不可能的,并且硬件(或OS)限制了这种行为。 关于这个主题还有另一个问题 ,但是这个问题声称不可能创建大于屏幕尺寸的SurfaceView,这是错误的,正如我在日志记录中发现的那样。 然而,似乎情况是摄像机预览无法增长到巨大的SurfaceView的全尺寸。 我的尝试: 我有一个相对布局,在它内部是一个FrameLayout,在其中我创建了一个SurfaceView。 整个相对布局的宽度设置在635dp以下,这是设备屏幕尺寸的两倍。 FrameLayout匹配此大小调整,SurfaceView也是如此(稍后以编程方式添加) 以下是获取和设置预览大小的代码。 在这里,我想让相机预览展开以填充整个FrameLayout(屏幕宽度的两倍)。 视图完全正常显示和破坏,因此我删除与此特定问题无关的代码,因为它分散了基本问题,并且我尝试轻松简单地将视图扩展为大于显示大小的视图。 public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { … public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { Camera.Parameters parameters = mCamera.getParameters(); final DisplayMetrics dm = this.getResources().getDisplayMetrics(); //getBestPreviewSize returns the best preview size, don’t worry //but […]

如何在Android N多窗口模式下确定正确的设备方向?

从多窗口文档 : 多窗口模式下禁用的function 当设备处于多窗口模式时,某些function被禁用或忽略,因为它们对于可能与其他活动或应用共享设备屏幕的活动没有意义。 这些function包括: 某些系统UI自定义选项已禁用; 例如,如果应用程序未以全屏模式运行,则无法隐藏状态栏。 系统忽略对android:screenOrientation属性的更改。 我得到了大多数应用程序,纵向和横向模式之间的区别是没有意义的,但是我正在使用SDK,其中包含用户可以进行任何活动的摄像机视图 – 包括支持多窗口模式的活动。 问题是摄像机视图包含显示摄像机预览的SurfaceView / TextureView,并且为了在所有活动方向上正确显示预览,需要有关正确活动方向的知识,以便可以正确旋转摄像机预览。 问题是我的代码通过检查当前配置方向(纵向或横向)和当前屏幕旋转来计算正确的活动方向。 问题是在多窗口模式下,当前配置方向不反映真实的活动方向。 这会导致相机预览旋转90度,因为Android报告的配置与方向不同。 我目前的解决方法是检查所请求的活动方向并以此为基础,但有两个问题: 请求的活动方向不必反映实际的活动方向(即可能仍未满足请求) 请求的活动方向可以是“后方”,“传感器”,“用户”等,它们不会显示有关当前活动方向的任何信息。 根据文档 ,在多窗口模式下实际上忽略了屏幕方向,因此1.和2.只是不起作用 即使在多窗口配置中,有没有办法可以稳健地计算正确的活动方向? 这是我目前使用的代码(请参阅有问题的部分的注释): protected int calculateHostScreenOrientation() { int hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); int rotation = getDisplayOrientation(wm); boolean activityInPortrait; if ( !isInMultiWindowMode() ) { activityInPortrait = (mConfigurationOrientation == Configuration.ORIENTATION_PORTRAIT); } else […]

从ACTION_IMAGE_CAPTURE Intent获取图像路径

您好我使用ACTION_IMAGE_CAPTURE使用Intent捕获图像,如下所示: Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); cameraIntent.putExtra( MediaStore.EXTRA_OUTPUT, (new File(Environment.getExternalStorageDirectory(), String.valueOf(System.currentTimeMillis()) + “.jpg”)) ); startActivityForResult(cameraIntent, 0); 我需要将图像存储在SD卡中,并使用onActivityResult方法检索该图像的路径。 我不知道如何获取当前捕获图像的图像路径。 如果有人知道请帮助。 谢谢

Android相机无法使用。 startPreview失败

我从LogCat收到这些错误: 10-30 00:31:51.494: D/CameraHal(1205): CameraHal setOverlay/1/00000000/00000000 10-30 00:31:51.494: E/CameraHal(1205): Trying to set overlay, but overlay is null!, line:3472 10-30 00:31:51.494: W/CameraService(1205): Overlay create failed – retrying … 10-30 00:31:52.526: E/CameraService(1205): Overlay Creation Failed! … 10-30 00:31:52.588: E/AndroidRuntime(5040): FATAL EXCEPTION: main 10-30 00:31:52.588: E/AndroidRuntime(5040): java.lang.RuntimeException: startPreview failed 10-30 00:31:52.588: E/AndroidRuntime(5040): at android.hardware.Camera.startPreview(Native Method) 10-30 00:31:52.588: E/AndroidRuntime(5040): […]

Android平板电脑和相机之间的USB bulkTransfer

我想使用bulkTransferfunction在相机和Android平板电脑设备之间交换数据/命令。 我写了这个Activity,但方法bulkTransfer返回-1 (错误状态)。 为什么会返回错误? public class MainActivity extends Activity { private TextView text; private int TIMEOUT = 1000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView) findViewById(R.id.txt); usbTest(); } private void usbTest() { UsbDevice device = (UsbDevice) getIntent().getParcelableExtra( UsbManager.EXTRA_DEVICE); if (device == null) text.setText(“device null”); else text.setText(“device not null”); UsbManager manager = […]

Android / Java:将字节数组保存到文件(.jpeg)

我正在开发一个Android应用程序,部分应用程序必须拍照并将它们保存到SD卡。 onPictureTaken方法返回一个包含捕获图像数据的字节数组。 我需要做的就是将字节数组保存到.jpeg图像文件中。 我试图在BitmapFactory.decodeByteArray(获取Bitmap)和bImage.compress(到OutputStream),普通OutputStream和BufferedOutputStream的帮助下完成此操作。 所有这三种方法似乎都给了我同样奇怪的错误。 我的Android手机(800万像素摄像头和一个体面的处理器),似乎保存了照片(尺寸看起来正确),但是以一种损坏的方式(图像被切片并且每个切片都被移动;或者我只得到几乎各种颜色的水平线) ; 奇怪的是,带有500万像素摄像头和快速处理器的Android平板电脑似乎可以正确保存图像。 所以我想也许处理器无法跟上保存大图像,因为我在大约3张图片后得到了OutOfMemory Exceptions(即使压缩质量为40)。 但那么内置的相机应用程序是如何做到的,而且速度也快得多? 我很确定(从调试)OutputStream写入所有数据(字节),它应该没问题,但它仍然被破坏。 ***简而言之,将字节数组保存到jpeg文件的最佳/最快方法是什么? 马克,提前谢谢 我尝试过的代码(和其他一些细微的变化): try { Bitmap image = BitmapFactory.decodeByteArray(args, 0, args.length); OutputStream fOut = new FileOutputStream(externalStorageFile); long time = System.currentTimeMillis(); image.compress(Bitmap.CompressFormat.JPEG, jpegQuality, fOut); System.out.println(System.currentTimeMillis() – time); fOut.flush(); fOut.close(); } catch (Exception e) { } 和 try { externalStorageFile.createNewFile(); FileOutputStream fos = new FileOutputStream(externalStorageFile); […]

使用与生成的video文件不同的预览大小录制video

我试图允许用户录制与录制时可以看到的实际屏幕预览不同的video。 这篇文章似乎可以从有关getSupportedVideoSizes函数的文档中获得,该函数声明: 如果返回的列表不为null,则返回的列表将包含至少一个Size,如果将摄像机用作video源,则必须将返回列表中的一个大小传递给MediaRecorder.setVideoSize()以用于摄像机应用程序。 在这种情况下,预览的大小可以与video记录期间记录的video的分辨率不同。 这表明某些手机将从此fn返回null(根据我的经验,Galaxy SIII会这样做),但对于那些不这样做的手机,可以提供与实际video不同的分辨率的预览。 这种理解是否正确? 有些手机允许这种行为吗? 尝试解决方案: 在设置video录制的漫长过程中使用的setPreviewDisplay函数的官方描述中 ,提到: 如果使用null surface调用此方法或根本不调用此方法,则介质记录器将不会更改摄像机的预览表面。 这似乎是我想要的,但不幸的是,如果我这样做,整个video录制过程完全搞砸了。 我假设在录制video的过程中,此函数不能传递null或根本不调用。 也许在其他情况下这是可以的。 不幸的是,这似乎对我没有帮助。 我唯一接下来的步骤是查看TextureView并使用预览纹理而不是典型的SurfaceView实现,以便使用openGL将纹理拉伸到我想要的大小(不同于实际分辨率)(并裁剪屏幕上的任何多余部分) ),然后使用Surface的Surface(SurfaceTexture surfaceTexture)构造函数为setPreviewDisplay函数构造一个Surface。 由于ICS下面的不兼容性,我想避免使用TextureView ,并且因为这会增加显着的复杂性。 这似乎是一个微妙的过程,但我希望有人可以在这方面提供一些建议。 谢谢。

录制video时启用相机闪光灯

我需要一种方法来控制Android设备上的摄像头闪光灯,同时录制video。 我正在制作一个闪光灯应用程序,并使用闪烁的闪光灯拍摄video将导致能够记录高速移动的物体,如风扇叶片。 只能通过启动video预览并在摄像机参数中设置FLASH_MODE_TORCH来启用闪光灯。 这看起来像这样: Camera c = Camera.open(); Camera.Parameters p = c.getParameters(); p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); c.setParameters(p); c.startPreview(); 预览开始后,我可以来回翻转该参数以打开和关闭灯光。 这很有效,直到我尝试录制video。 麻烦的是,为了将相机送到MediaRecorder,我首先要解锁它。 MediaRecorder m = new MediaRecorder(); c.unlock(); // the killer m.setCamera(c); 解锁后,我无法再更改摄像机参数,因此无法更改闪光灯状态。 我不知道是否真的可以这样做,因为我不是最好的java-hacking,但这是我所知道的: Camera.unlock()是一个本机方法,所以我无法真正看到它锁定我的方式背后的机制 Camera.Parameter有一个包含其所有参数的HashMap Camera.setParameters(Parameters)获取HashMap,将其转换为字符串,并将其传递给本机方法 我可以从HashMap消除所有参数但是TORCH-MODE,相机仍然会接受它 所以,我仍然可以访问相机,但它不会听我说的任何东西。 (这是Camera.unlock()的目的) 编辑: 检查本机代码后,我可以看到在CameraService.cpp中我对Camera.setParameters(Parameters)的调用被拒绝,因为我的进程ID与摄像头服务记录的进程ID不匹配。 所以这似乎是我的障碍。 EDIT2: 看起来MediaPlayerService是在录制video时控制摄像机的主要服务。 我不知道是否可能,但如果我能以某种方式在我自己的进程中启动该服务,我应该能够跳过Camera.unlock()调用。 EDIT3: 最后一个选择是,如果我能以某种方式获得指向CameraHardwareInterface的指针。 从它的外观来看,这是一个特定于设备的接口,可能不包括PID检查。 这个问题的主要问题是我能find指向它的唯一地方是在CameraService中,并且CameraService没有说话。 编辑4 :(几个月后) 在这一点上,我认为不可能做我原本想要的。 我不想删除有人确实回答的问题,但我并没有积极寻求答案。 (虽然,收到有效的答案会很棒。)

使用Google Vision API的媒体记录器

我正在使用Android vision API中的FaceTracker示例。 但是,我在录制video时遇到了困难,同时在它们上面绘制了叠加层。 一种方法是将位图存储为图像并使用FFmpeg或Xuggler将它们合并为video,但我想知道如果我们可以在预计投影时在运行时录制video,是否有更好的解决方案。 更新1:我使用媒体记录器更新了以下类,但录制仍然无法正常工作。 当我调用triggerRecording()函数时抛出以下错误: MediaRecorder:以无效状态调用:4 我在清单文件中有外部存储权限。 更新2: 我在代码中修复了上述问题,并在onSurfaceCreated回调中移动了setupMediaRecorder()。 但是,当我停止录制时,它会抛出运行时exception。 根据文档,如果没有video/音频数据,将抛出运行时exception。 那么,我在这里错过了什么? public class CameraSourcePreview extends ViewGroup { private static final String TAG = “CameraSourcePreview”; private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } private MediaRecorder mMediaRecorder; /** * Whether the app is […]