Android简单手电筒小项目教程

本文介绍了使用Android开发一个简单的手电筒应用,涉及主界面布局、自定义Dialog的创建和处理,以及FlashLightUtil类中对相机闪光灯的控制,包括权限请求、状态切换和CameraManager的使用。

项目构思

界面构成

主界面布局
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="50dp"
    tools:context=".MainActivity">


    <Button
        android:id="@+id/changeFlashBtn"
        android:layout_width="80dp"
        android:layout_height="140dp"
        android:layout_gravity="center"
        android:text="开启"
        android:textSize="30sp"/>
</LinearLayout>

因为只是一个手电筒项目所以界面比较简单,只需要一个居中的按钮就可以了

自定义Dialog布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/dialogTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="手电筒"
        android:textSize="20sp"
        android:layout_gravity="center_horizontal"/>
    <TextView
        android:id="@+id/dialogContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:layout_gravity="center_horizontal" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/dialogConfirm"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="确认"/>
        <View
            android:layout_width="20dp"
            android:layout_height="2dp"/>
        <Button
            android:id="@+id/dialogCancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="取消"/>
    </LinearLayout>

</LinearLayout>

代码逻辑

概览

项目中实现了一个MainActivity一个BaseActivity和一个工具类。MainActivity中实现了逻辑相关的操作,BaseActivity中实现了自定义log相关的功能,工具类中实现了获取闪光灯组件等方法。

BaseActivity

这里面定义了两个自定义Dialog的方法,当点击Dialog的确认按钮的时候就会进行闪光灯开启流程

public class BaseActivity extends AppCompatActivity {

    static Button changeFlashBtn;

    /**
     * 自定义手电筒开启Dialog
     * @param context
     */
    public void openFlashDialog(Context context){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.dialog_custom,null);
        TextView dialogContent = view.findViewById(R.id.dialogContent);
        dialogContent.setText("是否开启手电筒");
        final Dialog dialog = builder.create();
        dialog.show();
        dialog.getWindow().setContentView(view);

        Button confirmBtn = view.findViewById(R.id.dialogConfirm);
        Button cancelBtn = view.findViewById(R.id.dialogCancel);
        confirmBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
                FlashLightUtil.FlashStatus = true;
                changeFlashBtn.setText("关闭");
                try {
                    FlashLightUtil.openFlash(context);
                } catch (CameraAccessException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        cancelBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                dialog.dismiss();
            }
        });

    }

    /**
     * 自定义手电筒关闭Dialog
     * @param context
     */
    public void closeFlashDialog(Context context){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.dialog_custom,null);
        TextView dialogContent = view.findViewById(R.id.dialogContent);
        dialogContent.setText("是否关闭手电筒");
        final Dialog dialog = builder.create();
        dialog.show();
        dialog.getWindow().setContentView(view);

        Button confirmBtn = view.findViewById(R.id.dialogConfirm);
        Button cancelBtn = view.findViewById(R.id.dialogCancel);
        confirmBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FlashLightUtil.FlashStatus = false;
                changeFlashBtn.setText("开启");
                dialog.dismiss();
                try {
                    FlashLightUtil.closeFlash(context);
                } catch (CameraAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        cancelBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

    }



}
MainActivity
public class MainActivity extends BaseActivity{
    String TAG = "MainActivity";
    static final int REQUEST_CODE = 5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        changeFlashBtn = findViewById(R.id.changeFlashBtn);

        //弹窗获取权限
        if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},REQUEST_CODE);
        }
        //初始化
        try {
            FlashLightUtil.init(MainActivity.this);
        } catch (CameraAccessException e) {
            throw new RuntimeException(e);
        }


        changeFlashBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!FlashLightUtil.FlashStatus){
                    openFlashDialog(MainActivity.this);
                }else {
                    closeFlashDialog(MainActivity.this);

                }
            }
        });

    }
    //按返回键关闭摄像头
    @Override
    public void onBackPressed() {
        super.onBackPressed();

        try {
            FlashLightUtil.closeFlash(MainActivity.this);
        } catch (CameraAccessException e) {
            throw new RuntimeException(e);
        }
    }

    //获取权限弹窗的回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode != REQUEST_CODE ||grantResults[0]!=PackageManager.PERMISSION_GRANTED){
            Log.d(TAG, "onRequestPermissionsResult: 获取授权失败");
            //若未获取权限则关闭应用
            this.finish();
        }else if (isSupport()){
            //若获取了并且设备支持则初始化CamaraManager
            try {
                FlashLightUtil.init(MainActivity.this);
            } catch (CameraAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
FlashLightUtil
public  class FlashLightUtil {

    public FlashLightUtil() {

    }

    public static CameraManager cameraManager;
    private static String cameraId;
    static  String TAG = "FlashLightUtil";
    private static Handler handler;
    public static Boolean FlashStatus = false;



    //手电筒状态改变回调
    private static final CameraManager.TorchCallback torchCallback = new CameraManager.TorchCallback() {
        @Override
        public void onTorchModeUnavailable(@NonNull String cameraId) {
            super.onTorchModeUnavailable(cameraId);
        }

        @Override
        public void onTorchModeChanged(@NonNull String cameraId, boolean enabled) {
            super.onTorchModeChanged(cameraId, enabled);
            //如果手电筒状态与记录状态不相符则改变
            Log.d(TAG, "onTorchModeChanged: 手电筒状态改变了");
            if (FlashStatus !=enabled){
                if (FlashStatus){
                    changeFlashBtn.setText("开启");
                }else {
                    changeFlashBtn.setText("关闭");
                }
                FlashStatus  = !FlashStatus;
                Log.d(TAG, "onTorchModeChanged: 外界改变手电筒状态");
            }

        }

    };
    

    /**
     * 判=断是否API大于26的机型,因为CameraManager是5.0之后支持的
     * @return
     */
    public  static Boolean isSupport(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            return true;
        else
            return false;
    }


    /**
     * 初始化操作,获取CmareManager组件以及CamaraId
     * @param context
     * @throws CameraAccessException
     */
    public static void init(Context context) throws CameraAccessException {

        cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
        Log.d(TAG, "init: cameraManager"+cameraManager.toString());
        for (String id : cameraManager.getCameraIdList()){
            if (cameraManager.getCameraCharacteristics(id).get(CameraCharacteristics.FLASH_INFO_AVAILABLE)){
                cameraId = id;
            }
        }
        //后台监听闪光灯变化
        if (handler ==null){
            HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
            thread.start();
            handler = new Handler(thread.getLooper()){};
        }
        cameraManager.registerTorchCallback(torchCallback,handler);

        Log.d(TAG, "init: cameraId"+cameraId);
    }
    /**
     * 打开摄像头
     * @param context
     * @throws CameraAccessException
     */
    public  static void  openFlash(Context context) throws CameraAccessException {
        Log.d(TAG, "openFlash: entered");
        if (cameraId!=null){
            cameraManager.setTorchMode(cameraId,true);
            Log.d(TAG, "openFlash: setTorchMode Successed");
        }
    }

    /**
     * 关闭摄像头
     * @param context
     * @throws CameraAccessException
     */
    public static void closeFlash(Context context) throws CameraAccessException {
        if (cameraId!=null){
            cameraManager.setTorchMode(cameraId,false);
            Log.d(TAG, "openFlash: setTorchMode false Successed");
        }
    }



}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值