我可以在没有预览的情况下使用 Android 相机吗?

2023-11-23

我在 Android 中创建了一个应用程序,使用相机可以测量用户脸部到手机屏幕之间的距离。

问题描述:

现在我想让它在后台运行,以便在我使用其他应用程序时可以使用该功能。它的意思是我应该在没有预览的情况下打开服务中的相机,并在服务中处理它。

我还做了什么:

我在这里提到了一些问题

如何从应用程序后台录制视频:Android

如何在后台使用Android相机?

从相机拍摄照片而不进行预览

API 级别 16

我的服务档案

import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class RecorderService extends Service {
private static final String TAG = "RecorderService";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private static Camera mServiceCamera;
private boolean mRecordingStatus;
private MediaRecorder mMediaRecorder;
File path = android.os.Environment.getExternalStorageDirectory();


@Override
public void onCreate() {
    Log.i(TAG,"onCreate");
    mRecordingStatus = false;
    //mServiceCamera = CameraRecorder.mCamera;
    mServiceCamera = Camera.open(1);
    mSurfaceView = MainActivity.mSurfaceView;
    mSurfaceHolder = MainActivity.mSurfaceHolder;

    super.onCreate();
    if (mRecordingStatus == false)
        startRecording();
}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onDestroy() {
    Log.i(TAG,"onDestroy");

    stopRecording();
    mRecordingStatus = false;

    super.onDestroy();
}

public boolean startRecording(){
    Log.i(TAG,"startRecording");

    try {
        Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();

        //mServiceCamera = Camera.open();
        Camera.Parameters params = mServiceCamera.getParameters();
        mServiceCamera.setParameters(params);
        Camera.Parameters p = mServiceCamera.getParameters();

        final List<Size> listSize = p.getSupportedPreviewSizes();
        Size mPreviewSize = listSize.get(2);
        Log.v(TAG, "use: width = " + mPreviewSize.width
                + " height = " + mPreviewSize.height);
        p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
        mServiceCamera.setParameters(p);

        try {
            mServiceCamera.setPreviewDisplay(mSurfaceHolder);
            mServiceCamera.startPreview();
        }
        catch (IOException e) {
            Log.e(TAG, e.getMessage());
            e.printStackTrace();
        }

        mServiceCamera.unlock();

        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setCamera(mServiceCamera);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
        mMediaRecorder.setOutputFile(path+"/outputVideo.mp4");
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

        mMediaRecorder.prepare();
        mMediaRecorder.start();

        mRecordingStatus = true;

        return true;
    } catch (IllegalStateException e) {
        Log.d(TAG, e.getMessage());
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        Log.d(TAG, e.getMessage());
        e.printStackTrace();
        return false;
    }
}

public void stopRecording() {
    Log.i(TAG,"stopRecording");

    Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
    try {
        mServiceCamera.reconnect();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try{
        mMediaRecorder.stop();
    }catch (Exception ignored)
    {

    }
    mMediaRecorder.reset();
    mMediaRecorder.release();
    mServiceCamera.stopPreview();
    mServiceCamera.release();
    mServiceCamera = null;
}
}

你可以参考这个Question,其中讨论了如何在服务中进行视频录制。捕获图像的步骤与其相同。

为了达到您的要求,您可能需要:

  1. 在您的服务中获取相机实例。检查这个官方指南.
  2. 设置您的相机参数。使用如下 APICamera.getParameters(), Camera.setParameters(), Camera.Parameters.setPictureSize(int with, int height) and Camera.Parameters.setPictureFormat(int format)这样做。
  3. 准备一个用于存储图像的文件。你需要实施Camera.PictureCallback这样做。
  4. Call Camera.startPreview()在拍照之前。如果在拍照之前不调用此函数,则会出现异常。 (注意:你不需要做Camera.setPreviewdisplay(SurfaceHolder display) first.)
  5. Call camera.takePicture()为您服务。然后您就可以将捕获的图像存储在您指定的文件中。

工作后,不要忘记在生命周期中维护资源以正确获取/释放相机。

这是我的Github 上的示例代码,评论里也提到了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以在没有预览的情况下使用 Android 相机吗? 的相关文章

随机推荐

  • 从多个 Web.config 文件访问 appSettings

    我正在设计一个 ASP NET MVC4 Web 应用程序项目 在我的项目的根目录中 我有惯用的默认值Web config文件与我相应的元素 特别是我有几个appSettings定义的元素 作为演示这一点的示例摘录
  • Kubernetes:如何增加临时存储

    我有三个主节点 每个节点的磁盘大小为 80 GB 最近我遇到了这个问题 Normal Pulling 52s x2 over 6m17s kubelet 192 168 10 37 pulling image gcr io kubeflow
  • Facebook Connect 和 HTML5、xmlns 可用吗?

    Facebook Connect 及其 社交小部件 文档提到您需要添加xmlns归因于你的将使用它的页面上的标签 我明白那个xmlns用于 XML 名称间距 并且之前已将其与 XHTML 一起使用 然而 随着最近有关 HTML4 HTML5
  • 如何首先使用 EF 代码映射现有的 sql server 视图

    我对 EF 相当陌生 首先学习 EF 代码 我正在寻找一种知识来首先使用 EF 代码映射现有的 sql server 视图 我已经用 POCO 映射了我的视图 但出现以下错误 当我尝试从视图中获取数据时抛出以下错误 附加信息 支持 Test
  • PBS_MARQUEE 进度条 WinApi

    我正在尝试让 PBS MARQUEE 类型的进度条正常工作 我可以创建进度条 但我就是无法让它移动 如果发现这个 但我不清楚我必须做什么 事实证明 由于我将进度条作为资源而不是使用 CreateWindowEx 所以我必须使用 SetWin
  • ::(双冒号)在 DOS 批处理文件中意味着什么?

    我找到了这个程序web archive org http baiyunmanor com blog work get current date time in dos batch file This uses Windows Scripti
  • JPA 标准生成器:如何按顺序替换字符串并将其转换为数字?

    有人可以建议我如何使用 JPA Criteria 构建器 API 构建以下查询吗 SELECT id name date version FROM public upgradeTable order by CAST replace vers
  • 快速计算 .numpy 数组中每 N 行的平均值

    我有一个非常大的屏蔽 NumPy 数组 originalArray 有很多行和两列 我想取每两行的平均值originalArray并建立一个newArray其中每一行是两行的平均值originalArray so newArray行数为or
  • 在 javascript 或着色器中更好地乘以矩阵?

    我一直在看几个 webgl 示例 考虑MDN 的教程 他们的顶点着色器将顶点乘以透视矩阵和世界位置矩阵 gl Position uPMatrix uMVMatrix vec4 aVertexPosition 1 0 But the uMVM
  • Java序列化-Android反序列化

    我尝试过在 Java 和 Android 之间实现跨平台序列化 我使用了 Serialized 并将 Android 中的代码与桌面 Java 中的代码放在同一个包中 来源 java desktop 序列化 Student student
  • 从 Service Fabric 集群中删除应用程序

    我尝试使用服务结构资源管理器从服务结构中删除应用程序 我使用 删除应用程序 操作删除了我的应用程序 然后 当我尝试取消配置应用程序类型时 我收到错误消息 错误 版本 1 0 0 的应用程序类型无法取消配置为 它仍然包含活动的应用程序 我可以
  • “await Task.Run(); return;”之间的任何区别和“返回Task.Run()”? [复制]

    这个问题在这里已经有答案了 以下两段代码之间是否存在概念上的差异 async Task TestAsync await Task Run gt DoSomeWork and Task TestAsync return Task Run gt
  • 计算文件中的单词数

    我在计算文件中的字数时遇到问题 我采取的方法是 当我看到空格或换行符时 我就知道要计算单词数 问题是 如果我在段落之间有多行 那么我最终也会将它们算作单词 如果您查看 readFile 方法 您就可以看到我在做什么 您能帮助我并指导我如何解
  • Monad 变压器的使用

    我正在 Haskell 书中读到有关 monad 转换器的内容 作者提到如下 莫纳德呢 组合两个任意数据类型没有问题 有 Monad 实例 我们在使用 Compose 时已经看到了这一点 Maybe 和 list 都定义了 Monad 实例
  • Github - 文件 XYZ 为 126.80 MB;这超出了 GitHub 的文件大小限制 100.00 MB

    我有一个本地存储库 其中意外添加了一个大文件 现在我落后了近 100 个提交 当我尝试推送到 GitHub 时 出现错误 我需要帮助做任何我需要做的事情才能推送这个存储库的其余部分 我不需要这个文件 可以永久删除它 旁注 这是一个包含 IP
  • RoR 预编译资产在 rake asset:precompile 时失败 - 在基本上空的 application.js 上

    Running bundle exec rake assets precompile RAILS ENV production trace Execute assets precompile primary rake aborted Typ
  • 将带重音的文本转换为 ASCII 字符?

    我想在 Javascript 中将重音字母和各种编码转换为纯英文 ASCII 编码 并想知道有哪些可能的选项 我需要的是 clair becomes eclair b r becomes bar becomes privet becomes
  • R 中的对数刻度图

    我想绘制聚类系数和平均最短 路径作为 Watts Strogatz 模型参数 p 的函数如下 这是我的代码 library igraph library ggplot2 library reshape2 library pracma p l
  • 将顶点大小与 igraph 中的标签大小匹配

    我正在尝试使用 R 中的 igraph 绘制小型网络 网络中的每个顶点都有一个名称 相当于其标签 我想让每个顶点都有一个矩形符号 该符号足够大以适合其标签 这是我的主要灵感 使用 igraph 执行此操作的最佳方法是什么 编辑 更多信息 代
  • 我可以在没有预览的情况下使用 Android 相机吗?

    我在 Android 中创建了一个应用程序 使用相机可以测量用户脸部到手机屏幕之间的距离 问题描述 现在我想让它在后台运行 以便在我使用其他应用程序时可以使用该功能 它的意思是我应该在没有预览的情况下打开服务中的相机 并在服务中处理它 我还