Android:是不是可以从没有用户界面的服务中用相机拍照[重复]

Posted

技术标签:

【中文标题】Android:是不是可以从没有用户界面的服务中用相机拍照[重复]【英文标题】:Android: Is it possible to take a picture with the camera from a service with no UI [duplicate]Android:是否可以从没有用户界面的服务中用相机拍照[重复] 【发布时间】:2012-12-26 00:35:11 【问题描述】:

我能够使用相机拍照的唯一代码是从活动中运行的。我相当确定可以从服务中或从服务启动的 AsyncTask 中拍摄照片。

在我看来,相机 API 需要一个必须绑定到 UI 中的 SurfaceView。也许我错了。有没有人编写过可以从服务中获取照片的代码?

【问题讨论】:

【参考方案1】:

android 中使用 WindowManager 是可能的。

https://***.com/a/10268650/3047840

我应该说是的,你需要SurfaceView 来拍照,但它不必绑定到某个 xml 布局。您可以将其添加到即使在服务中也可以使用的WindowManager 类。所以这里的WindowManager会打开一个“窗口”让你在Android中做任何浮动效果。

具体来说,

您可以在WindowManager 中添加SurfaceView,并设置如下参数。

mPreview = new CameraPreview(this, mCamera, jpegCallback);
WindowManager wm = (WindowManager) this
        .getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
        PixelFormat.TRANSPARENT);

params.height = 1;
params.width = 1;

wm.addView(mPreview, params);

Android 具有此功能,而 ios 则没有。这就是为什么您可以在 Android 而不是 iOS 的主屏幕上激活 Facebook 聊天头。

Show facebook like chat head from a broadcast receiver in android

【讨论】:

需要注意的是,此方法需要 android.permission.SYSTEM_ALERT_WINDOW 权限,用户可能会遇到问题。 这对我有用,尽管您的代码示例缺少一些重要部分。 @Sam 想补充缺少的重要部分吗? @Ben,我不记得它们是什么了。但请参阅我对原始问题的回答以获取完整示例:***.com/a/27083867/238753【参考方案2】:

如果您还在寻找,这里有一些更完整的代码。在服务中工作(经过测试):

private void takePhoto() 

    System.out.println( "Preparing to take photo");
    Camera camera = null;

    int cameraCount = 0;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) 
        SystemClock.sleep(1000);

        Camera.getCameraInfo(camIdx, cameraInfo);

            try 
                camera = Camera.open(camIdx);
             catch (RuntimeException e) 
                System.out.println("Camera not available: " + camIdx);
                camera = null;
                //e.printStackTrace();
            
        try
            if (null == camera) 
                System.out.println("Could not get camera instance");
            else
                System.out.println("Got the camera, creating the dummy surface texture");
                //SurfaceTexture dummySurfaceTextureF = new SurfaceTexture(0);
                try 
                    //camera.setPreviewTexture(dummySurfaceTextureF);
                    camera.setPreviewTexture(new SurfaceTexture(0));
                    camera.startPreview();
                 catch (Exception e) 
                    System.out.println("Could not set the surface preview texture");
                    e.printStackTrace();
                
                camera.takePicture(null, null, new Camera.PictureCallback() 

                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) 
                        File pictureFileDir = getDir();
                        if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) 
                            return;
                        
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
                        String date = dateFormat.format(new Date());
                        String photoFile = "PictureFront_" + "_" + date + ".jpg";
                        String filename = pictureFileDir.getPath() + File.separator + photoFile;
                        File mainPicture = new File(filename);
                        addImageFile(mainPicture);

                        try 
                            FileOutputStream fos = new FileOutputStream(mainPicture);
                            fos.write(data);
                            fos.close();
                            System.out.println("image saved");
                         catch (Exception error) 
                            System.out.println("Image could not be saved");
                        
                        camera.release();
                    
                );
            
        catch (Exception e)
            camera.release();
        


    

【讨论】:

根据我的实验,虚拟SurfaceTexture 解决方法在 Nexus 4 和 HTC One m8 上有效,但在 Nexus 5 上失败:( 您在使用 Nexus 5 时遇到了什么问题? 这在我运行 Android 4.3 的 Sony Xperia M 上不起作用,因为使用了虚拟 SurfaceTexture 技术。【参考方案3】:

我认为这是不可能的,因为相机需要预览屏幕。见类似问题here

【讨论】:

可以在有效没有预览的情况下做到这一点,如您链接的问题所示。 @Gridtestmail 那么应用如何在用户不知情的情况下拍照? .他们启动了一项服务来拍照并使用虚拟表面视图/表面纹理。 play.google.com/store/apps/… 。我们怎样才能达到同样的效果?如果有的话,你能提供任何代码示例吗?

以上是关于Android:是不是可以从没有用户界面的服务中用相机拍照[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何从没有数组名称的android中的json中获取数据?

从没有异步任务的 JSON android 加载位图

从没有名称Android的嵌套数组JSON获取数据

Android中用到的网络基础知识

[译] 我从没理解过 JavaScript 闭包

如何为我在 Android 中用作背景的可绘制对象添加圆角?