Android custom camera setFocusAreas and setMeteringAreas not work on Samsung Devices

1.8k Views Asked by At

Maybe this question duplicate another question, but others i have not found a solution. I'm trying to write a custom android camera and the camera works fine on my device(HTC One).I tried some different devices, and works in one of them. but I'm having problems on Samsung devices. Do not turn off the autofocus feature on the device. Therefore, the device can not change the focus area. That is my touch event.

@Override
public boolean onTouchEvent(final MotionEvent event){

    Camera.Parameters cameraParameters = camera.getParameters();
    if (event.getAction() == MotionEvent.ACTION_UP){
        focusAreas.clear();
        meteringAreas.clear();
        Rect focusRect = calculateTapArea(event.getX(), event.getY(), 1f);
        Rect meteringRect = calculateTapArea(event.getX(), event.getY(), 1.5f);
        focusAreas.add(new Camera.Area(focusRect, 800));
        meteringAreas.add(new Camera.Area(meteringRect, 800));
        cameraParameters.setFocusAreas(focusAreas);
        cameraParameters.setMeteringAreas(meteringAreas);
        cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
        try{
            camera.setParameters(cameraParameters);

        } catch(Exception e){
            Log.e("Focus problem", e.toString());
            return false;
        }

        camera.autoFocus(new Camera.AutoFocusCallback() {                   
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                camera.cancelAutoFocus();
                Camera.Parameters  params = camera.getParameters();
                if(params.getFocusMode() != Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE){
                    params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                    camera.setParameters(params);
                }
            }
        });

        focusSound = new MediaPlayer();
        showSquareFocus();
        try {
            AssetFileDescriptor descriptor = this.getApplicationContext().getAssets()
                    .openFd("focus.wav");
            focusSound.setDataSource(descriptor.getFileDescriptor(),
                    descriptor.getStartOffset(), descriptor.getLength());
            descriptor.close();
            focusSound.prepare();
            focusSound.setLooping(false);
            focusSound.start();
            focusSound.setVolume(10,10);
            focusSound.setOnCompletionListener(new OnCompletionListener(){
                public void onCompletion(MediaPlayer mp){
                    mp.release();
                  }
                });
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return true;
}

Maybe need this code...

private Rect calculateTapArea(float x, float y, float coefficient) {
        int areaSize = Float.valueOf(FOCUS_AREA_SIZE * coefficient).intValue();
        int left = clamp((int) x - areaSize / 2, 0, width - areaSize);
        int top = clamp((int) y - areaSize / 2, 0, height - areaSize);
        RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
        matrix.mapRect(rectF);
        return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
    }

    private int clamp(int x, int min, int max) {
        if (x > max) {
            return max;
        }
        if (x < min) {
            return min;
        }
        return x;
    }
1

There are 1 best solutions below

0
On

I've experienced the same problem in a Samsung Galaxy S3. The solution I've found (even if its dirty) is to set an alternative focus mode before the desired one.

private void setFocusMode(final Camera camera, final String newFocusMode)
{
    // Apply an alternative focus mode

    Camera.Parameters parameters = camera.getParameters();
    final List<String> focusModes = parameters.getSupportedFocusModes();

    if (focusModes.contains(Parameters.FOCUS_MODE_FIXED) && newFocusMode.compareToIgnoreCase(Parameters.FOCUS_MODE_FIXED) == false)
    {
        parameters.setFocusMode(Parameters.FOCUS_MODE_FIXED);
    }
    else if (focusModes.contains(Parameters.FOCUS_MODE_INFINITY) && newFocusMode.compareToIgnoreCase(Parameters.FOCUS_MODE_INFINITY) == false)
    {
        parameters.setFocusMode(Parameters.FOCUS_MODE_INFINITY);
    }
    else if (focusModes.contains(Parameters.FOCUS_MODE_MACRO) && newFocusMode.compareToIgnoreCase(Parameters.FOCUS_MODE_MACRO) == false)
    {
        parameters.setFocusMode(Parameters.FOCUS_MODE_MACRO);
    }
    else if (focusModes.contains(Parameters.FOCUS_MODE_AUTO) && newFocusMode.compareToIgnoreCase(Parameters.FOCUS_MODE_AUTO) == false)
    {
        parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
    }

    camera.setParameters(parameters);

    // Now apply the desired focus mode

    parameters = camera.getParameters();
    parameters.setFocusMode(newFocusMode);
    camera.setParameters(parameters);
}