Turn ON / OFF Flashlight using SurfaceView

2019-01-19 18:54发布

问题:

I am writing an Android Camera App and trying to implement Flash functionality, I am using SurfaceView, whenever i do tap on flash button toggle works but flash not coming... see my below code i have used to Turn ON/OFF Flashlights.

Complete code:--

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

        setContentView(R.layout.activity_camera);

          preview=(SurfaceView)findViewById(R.id.surface);     
                previewHolder=preview.getHolder();    
                previewHolder.addCallback(surfaceCallback);    
                previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
                previewHolder.setFixedSize(getWindow().getWindowManager()     
                        .getDefaultDisplay().getWidth(), getWindow().getWindowManager() 
                        .getDefaultDisplay().getHeight()); 


            btnFlash = (ImageButton) findViewById(R.id.btnFlash);               
            /*
             * First check if device is supporting flashlight or not
             */
            hasFlash = getApplicationContext().getPackageManager()
                    .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

            if (!hasFlash) {
                // device doesn't support flash
                // Show alert message and close the application
                AlertDialog alert = new AlertDialog.Builder(CameraLauncherActivity.this)
                        .create();
                alert.setTitle("Error");
                alert.setMessage("Sorry, your device doesn't support flash light!");
                alert.setButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        // closing the application
                        finish();
                    }
                });
                alert.show();
                return;     
            }

            // displaying button image
            toggleButtonImage();

            btnFlash.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (isFlashOn) {
                        // turn off flash
                        turnOffFlash();
                    } else {
                        // turn on flash
                        turnOnFlash();
                    }                  
                }
            });                    
    }       

/*
 * Turning On flash
 */
private void turnOnFlash() {
    if (!isFlashOn) {
        if (camera == null || params == null) {
            return;
        }

        params = camera.getParameters();
        params.setFlashMode(Parameters.FLASH_MODE_ON);
        camera.setParameters(params);
        isFlashOn = true;

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

/*
 * Turning Off flash
 */
private void turnOffFlash() {
    if (isFlashOn) {
        if (camera == null || params == null) {
            return;
        }

        params = camera.getParameters();
        params.setFlashMode(Parameters.FLASH_MODE_OFF);
        camera.setParameters(params);
        isFlashOn = false;

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

/*
 * Toggle switch button images
 * changing image states to on / off
 * */
private void toggleButtonImage(){
    if(isFlashOn){
        btnFlash.setImageResource(R.drawable.green_button);
    }else{
        btnFlash.setImageResource(R.drawable.red_button);
    }
}

@Override
public void onResume() {  
    super.onResume();   
    camera=Camera.open(); 
    }  

@Override   
public void onPause() {  
    super.onPause();  
    if (inPreview) {  
    camera.stopPreview();   }   
    camera.release();   
    camera=null;   
    inPreview=false;         
    }   


private Camera.Size getBestPreviewSize(int width, int height,Camera.Parameters parameters){   
    Camera.Size result=null;   
    for (Camera.Size size : parameters.getSupportedPreviewSizes()) 
    {   
        if (size.width<=width && size.height<=height)
        {
            if (result==null) {  
                result=size;   
            }   else {  
                int resultArea=result.width*result.height; 
                int newArea=size.width*size.height;  
                if (newArea>resultArea) {   
                    result=size;   
                    }  
                }   
            }   
        }   
    return(result);   
    }    
    SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback(){

    public void surfaceCreated(SurfaceHolder holder) {     
        try {        
            camera.setPreviewDisplay(previewHolder); 
            }   catch (Throwable t) {   
                Log.e("PreviewDemo-surfaceCallback",
                        "Exception in setPreviewDisplay()", t);
                Toast.makeText(CameraLauncherActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();       
                }     
            }      

    public void surfaceChanged(SurfaceHolder holder,int format, int width,int height) {
        params = camera.getParameters();       
        params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
        Camera.Size size=getBestPreviewSize(width, height,                                           
                params);       
        if (size!=null) {      
            params.setPreviewSize(size.width, size.height);
            camera.setParameters(params);       
            camera.startPreview();       
            inPreview=true;   
            ZoomControls zoomControls = (ZoomControls) findViewById(R.id.zoomControls);

            if (params.isZoomSupported()) {
                final int maxZoomLevel = params.getMaxZoom();
                Log.i("max ZOOM ", "is " + maxZoomLevel);
                zoomControls.setIsZoomInEnabled(true);
                zoomControls.setIsZoomOutEnabled(true);

                zoomControls.setOnZoomInClickListener(new OnClickListener(){
                    public void onClick(View v){
                        if(currentZoomLevel < maxZoomLevel){
                            currentZoomLevel++;
                            //mCamera.startSmoothZoom(currentZoomLevel);
                            params.setZoom(currentZoomLevel);
                            camera.setParameters(params);
                        }
                    }
                });

                zoomControls.setOnZoomOutClickListener(new OnClickListener(){
                    public void onClick(View v){
                        if(currentZoomLevel > 0){
                            currentZoomLevel--;
                            params.setZoom(currentZoomLevel);
                            camera.setParameters(params);
                        }
                    }
                });    
            }
            else
                zoomControls.setVisibility(View.GONE);
            }     
        }      

    public void surfaceDestroyed(SurfaceHolder holder) {

        }   
    };            
    }

回答1:

A few things I can think of:

Remember to add the features and requirements on the manifest for a camera app:

<!-- Camera Requirement -->
<uses-feature android:name="android.hardware.camera" />

<!-- Camera Permissions -->
<uses-permission android:name="android.permission.CAMERA" />     

<!-- Features -->
<uses-feature android:name="android.hardware.camera.flash" />
<uses-feature android:name="android.hardware.camera.autofocus" />

If you want to use it as flashlight you can do what @yoah said:

parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH)

If not, to turn flash on which will come out when you take the picture, you use:

parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON)

I wrote a custom camera app recently, but haven't uploaded it to Github yet, it has all the basic functions working.



回答2:

Try to use

parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH)

Setting FLASH_MODE_ON means that flash will show when taking a picture