【问题标题】:Flashlight in Android fragment - SurfaceViewAndroid片段中的手电筒 - SurfaceView
【发布时间】:2014-09-17 12:58:14
【问题描述】:

我正在尝试为本地音乐会开发手电筒应用程序。这是一个更大的应用程序的一部分,所以它在一个片段中。这是代码:

首先我声明了这个类和它的变量:

public class ConcertFragment extends Fragment {

    ToggleButton btnFlashlight;
    View rootView;

    private Camera cam;
    private boolean hasFlash;
    boolean hasCamera;
    boolean isFlashOn;
    Parameters params;

    public ConcertFragment() {
    }

接下来是 onActivityCreated 方法,它返回 getCamera 方法(进一步声明):

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

        getCamera();
    }

然后我创建构建布局的onCreateView 方法:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        rootView = inflater.inflate(R.layout.fragment_concert, container, false);

        hasFlash = getActivity().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(getActivity()).create();

            alert.setTitle("No Flash");
            alert.setMessage("Sorry, device is not flash supported.");
            alert.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new android.content.DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            });
            alert.show();
        }

        btnFlashlight = (ToggleButton) rootView.findViewById(R.id.toggleButton);
        btnFlashlight.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                if (isFlashOn) {
                    // turn off flash
                    turnOffFlash();
                } else {
                    // turn on flash
                    turnOnFlash();
                }
            }
        });

        return rootView;
    }

开启闪光灯的方法:

    private void turnOnFlash() {
        if (!isFlashOn) {
            if (cam == null || params == null) {
                return;
            }

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

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

关闭闪光灯的方法:

    private void turnOffFlash() {
        if (isFlashOn) {
            if (cam == null || params == null) {
                return;
            }

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

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

相机参数设置方法:

       private void getCamera() {
            if (cam != null) {
                try {
                    cam = Camera.open();
                    params = cam.getParameters();
                    cam.startPreview();
                    hasCamera = true;

                } catch (RuntimeException e) {
                    Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
                }
            }
       }        

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

打开和关闭手电筒的切换按钮会打开和关闭,但我的 Nexus 5 背面的手电筒永远不会打开。

我使用的相关权限如下:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.VIBRATE" />

有人可以帮忙吗?

【问题讨论】:

  • 您介意剥离代码以仅显示代码的相关部分吗?真的很长。
  • 打开闪光灯和关闭闪光灯这两个例程似乎很好。您是否设置了正确的权限以允许使用此功能?
  • 有没有人发现我该如何解决这个问题?任何帮助表示赞赏:)

标签: android android-fragments surfaceview flashlight


【解决方案1】:

我也在努力解决同样的问题。您需要在布局中的按钮上方添加 SurfacePreview:

 <SurfaceView
    android:id="@+id/PREVIEW"
    android:layout_width="1dp"
    android:layout_height="1dp"/>

目前我的 Fragment 看起来像这样:

public class FlashlightFragment extends Fragment implements SurfaceHolder.Callback {

ImageButton btnSwitch;
//flag to detect flash is on or off
private boolean isLighOn = false;

private Camera camera;
Parameters params;

@Override
public void onStart() {
    super.onStart();
    SurfaceView preview = (SurfaceView)getView().findViewById(R.id.PREVIEW);
    SurfaceHolder mHolder = preview.getHolder();
    mHolder.addCallback(this);
}

@Override
public void onPause(){
    super.onPause();
    turnOffFlash();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.flashlight_fragment,
            container, false);

    // flash switch button
    btnSwitch = (ImageButton) view.findViewById(R.id.flashlight_button);

    // displaying button image
    toggleButtonImage();

    // Switch button click event to toggle flash on/off
    btnSwitch.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (isLighOn) {
                // turn off flash
                turnOffFlash();
            } else {
                // turn on flash
                turnOnFlash();
            }
        }
    });

    return view;
}

// Turning On flash
private void turnOnFlash() {

    if (!isLighOn) {
        if (camera == null || params == null) {
            return;
        }
        params = camera.getParameters();
        params.setFlashMode(Parameters.FLASH_MODE_TORCH);
        camera.setParameters(params);
        camera.startPreview();
        isLighOn = true;

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

}

// Turning Off flash
private void turnOffFlash() {

    if (isLighOn) {
        if (camera == null || params == null) {
            return;
        }

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

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

/*
 * Toggle switch button images
 * changing image states to on / off
 * */
private void toggleButtonImage(){
    if(isLighOn){
        btnSwitch.setImageResource(R.drawable.icon_bulb_on);
    }else{
        btnSwitch.setImageResource(R.drawable.icon_bulb_off);
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder,int format,int width,int height)   {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (camera != null) {
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        camera = null;
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    if (camera == null) {
        camera = Camera.open();
        params = camera.getParameters();
        try {
            camera.setPreviewDisplay(holder);
        } catch (IOException e) {
            camera.release();
            camera = null;
        }
    }
}

这似乎在我的 Nexus 5 上运行良好,但在 Xperia Z 上强制关闭 camera.setPreviewDisplay(mHolder); 我还不能解决这个问题。

希望这会有所帮助。

【讨论】:

  • 嗨@Niels,我会试试的,然后会回复你。
  • 谢谢 Neils,它成功了 :) 如果我设法让它在全球范围内的 Android 操作系统上运行,我会更新这篇文章,而不仅仅是在我的 Nexus 5 上。在此期间,请您发送给我们LogCat 与您在 Xperia 上遇到的错误?
  • 它工作得很好,现在似乎正在 xperia 上工作,我猜这是与自定义 rom 相关的东西。
  • 欢迎您,如果您发现任何代码改进,请告诉我,我是 Android 的初级开发人员,所以可能会犯一些错误。
  • 这对我有用(Xperia Z3),谢谢! Android API 指南中的小注释:注意:使用 Camera.open() 时始终检查异常。如果相机正在使用或不存在,未能检查异常将导致您的应用程序被系统关闭。
猜你喜欢
  • 2020-01-12
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
相关资源
最近更新 更多