之前在项目中开发了一个手电筒应用,今天就拿出来给大家分享一下。
应用的架构很简单,就单纯的一个布局加一个主Activity,那么先来看一下资源图片有那些。
最后一张是桌面菜单图标,倒数第二张是透明的一个按钮图标。第一张和第二张分别是手电筒打开和关闭的资源图片。好了,然后来看一下文件的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_flashlight"
>
<RelativeLayout
android:id="@+id/bg_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@drawable/bg_flashlight_off" >
<ImageView
android:id="@+id/btn_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="148dp"
android:src="@drawable/btn_flash_light" />
</RelativeLayout>
</RelativeLayout>
大家应该能够看出来,手电筒点击进入的首次状态是打开的。最后看一下最关键的控制代码:
package com.example.flashlight;
import java.util.List;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.Vibrator;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.app.Activity;
import android.content.Context;
public class MainActivity extends Activity implements OnClickListener {
private static final String TAG = "hello";
public ImageView btnimageView = null;
public RelativeLayout bgmageView = null;
private Camera camera;
private boolean isOpen = true;
public final static int OPEN_CAMEERA = 1011;
public final static int OPEN_LIGHT = 1012;
public final static int CLOSE_LIGHT = 1013;
private Vibrator vibrator;//振动器
private Thread newThread;
private boolean isTrue = true;
private long mExitTime = 0;
long []pattern = {100,200};//等待0.1秒后 振动0.2秒
PowerManager.WakeLock wakeLock;//保持屏幕恒亮
private boolean mCameraFinish = false;
private Object mLock = new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉状态栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD,
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.main);
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
btnimageView = (ImageView) findViewById(R.id.btn_image);
bgmageView = (RelativeLayout) findViewById(R.id.bg_image);
bgmageView.setBackgroundResource(R.drawable.bg_flashlight_off);
btnimageView.setImageResource(R.drawable.btn_flash_light);
btnimageView.setOnClickListener(this);
bgmageView.setBackgroundResource(R.drawable.bg_flashlight);
btnimageView.setImageResource(R.drawable.btn_flash_light);
vibrator.vibrate(pattern, -1);
newThread = new Thread(){
public void run(){
Log.i(TAG, "camera open start");
synchronized(mLock){
if(mCameraFinish){
return;
}
camera = Camera.open();//打开照相机
if(camera != null){
Parameters params = camera.getParameters();//掉用闪光灯
List<String> list = params.getSupportedFlashModes();
if(list.contains(Parameters.FLASH_MODE_TORCH)){
params.setFlashMode(Parameters.FLASH_MODE_TORCH);//设置照相机参数FLASH_MODE_TORCH 持续的亮灯
}else{
Toast.makeText(getApplicationContext(), "此设备不支持闪光灯模式",
Toast.LENGTH_SHORT).show();
}
camera.setParameters(params);
camera.startPreview();//开始亮灯
isOpen = true;
}
}
Log.i(TAG, "camera open end camera = "+camera);
}
};
newThread.start();
}
Handler handler = new Handler(Looper.getMainLooper()){
public void handleMessage(Message msg){
switch (msg.what) {
case OPEN_CAMEERA:
camera = Camera.open();//打开照相机
break;
case OPEN_LIGHT:
synchronized(mLock){
if(camera != null){
Parameters params = camera.getParameters();//掉用闪光灯
List<String> list = params.getSupportedFlashModes();
if(list.contains(Parameters.FLASH_MODE_TORCH)){
params.setFlashMode(Parameters.FLASH_MODE_TORCH);//设置照相机参数FLASH_MODE_TORCH 持续的亮灯
}else{
Toast.makeText(getApplicationContext(), "此设备不支持闪光灯模式",
Toast.LENGTH_SHORT).show();
}
camera.setParameters(params);
camera.startPreview();//开始亮灯
isOpen = true;
}
}
break;
case CLOSE_LIGHT:
synchronized(mLock){
if(isOpen){
if(camera != null){
Parameters closeParameters = camera.getParameters();
closeParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(closeParameters);
camera.stopPreview();//关掉灯
isOpen = false;
}
}
}
break;
default:
break;
}
}
};
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_image:
Log.i("lyj_tag", "isOpen = "+isOpen);
synchronized(mLock){
if(isOpen){
bgmageView.setBackgroundResource(R.drawable.bg_flashlight_off);
btnimageView.setImageResource(R.drawable.btn_flash_light);
handler.sendEmptyMessage(CLOSE_LIGHT);
vibrator.vibrate(pattern, -1);
}else{
bgmageView.setBackgroundResource(R.drawable.bg_flashlight);
btnimageView.setImageResource(R.drawable.btn_flash_light);
handler.sendEmptyMessage(OPEN_LIGHT);
vibrator.vibrate(pattern, -1);
}
}
break;
default:
break;
}
}
protected void onDestroy(){
super.onDestroy();
releaseCamera();
}
public void releaseCamera(){
synchronized(mLock){
if(camera != null){
camera.release();
camera = null;
}
}
}
public void onStop(){
super.onStop();
vibrator.cancel();
releaseCamera();
}
protected void onResume(){
super.onResume();
//启用屏幕常亮功能
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE,
"test");
wakeLock.acquire();
}
protected void onPause(){
super.onPause();
Log.i(TAG, "onPause Thread end");
if(wakeLock != null){
wakeLock.release();
Log.i(TAG, "onPause wakeLock end");
}
一定要释放Camera,否则会导致手机屏幕不能主动灭屏
releaseCamera();
finish();
}
public boolean onKeyDown(int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_BACK){//按back键的时候 释放照相机
synchronized(mLock){
if(camera != null){
releaseCamera();
}else{
//mCameraRelease = false;
}
mCameraFinish = true;
}
}
if(keyCode == KeyEvent.KEYCODE_HOME){//按home键的时候 释放照相机
synchronized(mLock){
if(camera != null){
releaseCamera();
finish();
}else{
//mCameraRelease = false;
}
mCameraFinish = true;
}
}
return super.onKeyDown(keyCode, event);
}
}
对了,最后一定不要忘了在应用的AndroidManifest.xml文件中加上这些权限,否则应用会抛出异常。
<!-- 设置权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-feature android:name="android.hardware.camera"/>
代码关键的地方我都做了注释,看了代码后大家应该都能明白,需要说明的是:首次点击进入手电筒是打开的,按Back键后手电筒是关闭的,如果按Home键或者Power键,手电筒是保持常亮的。当然如果需要关闭的话稍微修改一下代码就可以了。好了,看一下手电筒打开和关闭的效果图: