如何在安卓手机上同时打开手电筒和前置摄像头

5

在我的应用程序的一个需求中,我需要弹出一个包含前置摄像头预览的活动界面,同时我也需要开启闪光灯。然而,我注意到我可以同时开启后置摄像头和闪光灯,但无法同时开启前置摄像头和闪光灯。以下是我的代码:

    public class Cam extends Activity {

        private static int cameraId = 0;
        private Camera camera;

        //Adding for camera preview
        public static FrameLayout preview;
        public static CameraPreview mPreview;
        Context context;

        ImageButton btnSwitch;
        private boolean isFlashOn;
        private boolean hasFlash;
        Parameters params;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            Log.e("Cam","Inside onCreate");
            setContentView(R.layout.cam);
            context = getApplicationContext();      

            btnSwitch = (ImageButton) findViewById(R.id.btnSwitch);

            hasFlash = getApplicationContext().getPackageManager()
                    .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

            startCamera();

            // displaying button image
            toggleButtonImage();        

            btnSwitch.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    if (isFlashOn) {
                        turnOffFlash();
                    } else {
                        turnOnFlash();
                    }
                }
            });     
        }

        @Override
        protected void onPause() {
            super.onPause();

            turnOffFlash();

            Log.e("Cam","Inside onPause");
            try {
                if (camera != null) {
                    camera.release();
                    camera = null;
                    preview.removeView(mPreview);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void onResume() {
            super.onResume();

            Log.e("Cam","Inside onResume");
            try {
                if(camera ==null) {
                    Log.d("Cam","in resume,camera is  null");
                    try {
                        camera = android.hardware.Camera.open(cameraId); //opens front cam              
                        // camera = Camera.open(); when I use this I can on/off the flashlight,since I am using the back camera.
                        mPreview = new CameraPreview(this, camera);
                        preview = (FrameLayout) findViewById(R.id.camera_preview);
                        preview.addView(mPreview);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            Log.e("Cam","Inside onDestroy");
            if (camera != null) {
                try {
                    camera.release();
                    camera = null;
                    preview.removeView(mPreview);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        private void startCamera() {

                    Log.e("Cam","Inside doInBackground");
                    String msg = "";
                    // Do we have a camera?
                    try {
                        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {

                        } else {
                            cameraId = AppFunctions.findFrontFacingCamera();//A function that returns 0 for front camera
                            if (cameraId < 0) {

                            } else {

                                try {
                                    camera = Camera.open(cameraId);//opens front cam 
                                    // camera = Camera.open(); when I use this I can on/off the flashlight,since I am calling the back camera.
                                    params = camera.getParameters(); 
                                    Log.e("Cam","camera id" + cameraId);
                                    Log.e("Cam","params" + params);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }

                                try {
                                    mPreview = new CameraPreview(getApplicationContext(), camera);
                                    preview = (FrameLayout) findViewById(R.id.camera_preview);
                                    preview.addView(mPreview);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    } catch (Exception e3) {
                        e3.printStackTrace();
                    }
        }

        private void turnOnFlash() {
            Log.v("Cam","Inside turnOnFlash");
            if (!isFlashOn) {
                if (camera == null || params == null) {
                    Log.v("Cam","camera or param is null");
                    return;
                }

                params.setFlashMode(Parameters.FLASH_MODE_TORCH);
                camera.setParameters(params);
                camera.startPreview();
                isFlashOn = true;

                // changing button/switch image
                toggleButtonImage();
            }

        }

        /*
         * Turning Off flash
         */
        private void turnOffFlash() {
            Log.v("Cam","Inside turnOffFlash");
            if (isFlashOn) {
                if (camera == null || params == null) {
                    Log.v("Cam","camera or param is null");
                    return;
                }
                params.setFlashMode(Parameters.FLASH_MODE_OFF);
                camera.setParameters(params);
                camera.stopPreview();
                isFlashOn = false;

                // changing button/switch image
                toggleButtonImage();
            }
        }

        private void toggleButtonImage(){
            if(isFlashOn){
                btnSwitch.setImageResource(R.drawable.btn_switch_on);
            }else{
                btnSwitch.setImageResource(R.drawable.btn_switch_off);
            }
        }
    }

清单文件

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.front" />
<permission android:name="android.permission.FLASHLIGHT" />  

我该如何同时开启手电筒和前置摄像头?非常感谢您的帮助!

请看这个答案:http://stackoverflow.com/a/25020259/1116216 - Michele La Ferla
@MicheleLaFerla:在这里我相信他们使用'camera = Camera.open();',这默认打开后置摄像头。我需要使用前置摄像头。此外,我发现使用前置摄像头对象创建的参数无法帮助我打开/关闭闪光灯。 - Basher51
如果按照您的要求,我的理解是您只需要打开手电筒:“理想情况下,如果我们可以在不使用任何相机对象的情况下操作手电筒,那将是最好的。” 如果我理解有误,请纠正我。这似乎是您正在寻找的内容:https://dev59.com/TG025IYBdhLWcg3wVkef - Surendra Kumar
@SurendraKumar:感谢您的建议。首先,我不仅需要打开闪光灯,同时我还想能够同时使用前置摄像头。其次,到目前为止,我看到的所有解决方案都是利用后置摄像头对象来操作闪光灯(我不明白为什么Android将使用闪光灯与相机对象绑定/限制了起来:/)。 - Basher51
@SurendraKumar:第三点,你有没有注意到你建议的链接中所有的解决方案都在使用手电筒之前使用了camera.open()?这一步默认打开后置摄像头。如果我尝试使用前置摄像头对象来使用手电筒,则手电筒无法打开/关闭。似乎安卓已经将手电筒与仅使用后置摄像头对象参数操作绑定在一起。 - Basher51
不应该是这样的。我会检查并更新你。 :) - Surendra Kumar
3个回答

1
手电筒
 public void onToggleClicked(View view) {
    PackageManager pm = context.getPackageManager();
    final Parameters p = camera.getParameters();
    if (isFlashSupported(pm)) {
        boolean on = ((ToggleButton) view).isChecked();
        if (on) {
            Log.i("info", "torch is turn on!");
            p.setFlashMode(Parameters.FLASH_MODE_TORCH);
            camera.setParameters(p);
            camera.startPreview();
        } else {
            Log.i("info", "torch is turn off!");
            p.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(p);
            camera.stopPreview();
        }

相机:
 ImageButton ib = (ImageButton) findViewById(R.id.buttonToast);
    ib.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(i, CAPTURE_IMAGE_CAPTURE_CODE);
        }
    });

对于代码行'final Parameters p = camera.getParameters();',你是否在使用camera = Camera.open()?如果是这样,那将打开后置摄像头,而这个参数'p'不能帮助打开或关闭闪光灯,因为它来自于后置摄像头对象。如果我错了,请纠正我。 - Basher51

1
尝试在后台打开闪光灯,然后打开前置摄像头。实际上,您可以在后台中打开前置摄像头和闪光灯。
以下是如何在后台打开闪光灯的方法: this 以下是如何在后台打开相机的方法: this

在您分享的两个链接中,我看到相机对象是使用“camera = Camera.open();”创建的。我相信这默认打开后置摄像头。使用此后置摄像头对象创建的参数未能帮助我打开/关闭手电筒。我尝试了与我的问题中所示相同的操作。如果我错了,请纠正我。 - Basher51

0
以下代码检查前置摄像头的可用性:
private Camera openFrontFacingCameraGingerbread() {
    int cameraCount = 0;
    Camera cam = null;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
        Camera.getCameraInfo(camIdx, cameraInfo);
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            try {
                cam = Camera.open(camIdx);
            } catch (RuntimeException e) {
                Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
            }
        }
    }

    return cam;
}

然后在 AndroidManifest.xml 文件中添加以下权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />

注意:此功能适用于Gingerbread(2.3)及以上版本的Android。

我建议使用surfaceView,就像this示例中一样,来实现一个可工作的手电筒。

希望这可以帮到你 :)


我的代码中的这一行 - 'cameraId = AppFunctions.findFrontFacingCamera();' 的功能是获取前置摄像头的ID,并且运行良好。我遇到的问题是当我创建一个参数 'params = camera.getParameters();' 时,它使用了前置摄像头对象。当使用这个参数来打开/关闭闪光灯时,它无法工作。如果这个参数来自后置摄像头对象,那么闪光灯就会正常工作。 - Basher51
它应该在循环可用摄像头的数量时打开前置摄像头。 - Michele La Ferla
是的,我同意。所有的都正常工作,我能够打开前置摄像头。但是在这个阶段,当我使用前置摄像头对象创建参数(params = camera.getParameters();)并将其用于手电筒(params.setFlashMode(Parameters.FLASH_MODE_TORCH);)时,我发现我无法操作手电筒。 - Basher51
明白了。那么,您需要创建两个不同的摄像头实例,以便设备加载前置镜头和后置闪光灯。就我个人而言,我从未编写过这样的程序,但是我能理解您想要做的事情。 - Michele La Ferla
我认为系统不允许同时打开两个摄像头。我已经上传了我的示例应用程序源代码,网址为-'https://drive.google.com/file/d/0B_gufkZm3wBEbzF5Vms3S21pVzQ/view?usp=sharing'。如果您想查看我的问题,可以运行该应用程序/查看源代码。 - Basher51
我已经为您尝试了快速搜索。以下内容似乎可以在至少具有前置和后置摄像头的HTC手机上使用:https://bitbucket.org/jens_grubert/androiddualcameracapture/ - Michele La Ferla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接