Android开发四:插曲1--做一个安卓手电筒

连续学了好几天了,今天找个案例做做,没学几天不会没关系,只有在做真正的程序才能快速的提高自己。

今天做一个安卓的手电筒,现在网上的安卓手电筒不外乎也就两种,第一种,用屏幕照明,第二种,用闪光灯照明。我都做了个,但是我的手机是V880,没有闪光灯,没办法测试,发在最后,哪位大哥下载下来安装了试试,给留个话,不胜感激。

先说用屏幕照明的,思路是把屏幕设置成全屏的,然后亮度跳成最高,设置保持常亮。然后可以加上一个颜色选择对话框,能让用户选择灯光颜色就行了,实现起来不太麻烦。先说布局文件,特别简单,就是一个LinearLayout。代码如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:orientation
="vertical"
android:id
="@+id/main" >

</LinearLayout>

这个和以前用的布局有的差别,我给LinearLayout加了一个id,这个id在代码里面要用到。
然后下面是后台的代码,注释的已经很清楚了

 1 package com.yyj.Lighter;
2
3 import com.yyj.Lighter.ColorPickerDialog.OnColorChangedListener;
4 import android.app.Activity;
5 import android.os.Bundle;
6 import android.view.MotionEvent;
7 import android.view.Window;
8 import android.view.WindowManager;
9 import android.view.WindowManager.LayoutParams;
10 import android.widget.LinearLayout;
11 import android.widget.Toast;
12 import com.yyj.Lighter.R;
13
14 public class RadioButtontestActivity extends Activity {
15 /** Called when the activity is first created. */
16 LinearLayout main;
17 @Override
18 public void onCreate(Bundle savedInstanceState) {
19 super.onCreate(savedInstanceState);
20
21 //设置无标题
22 requestWindowFeature(Window.FEATURE_NO_TITLE);
23 //设置全屏
24 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
25
26 setContentView(R.layout.main);
27 //得到LinearLayout,这一句用到了main.xml中定义的LinearLayout的id
28 main=(LinearLayout)findViewById(R.id.main);
29 //设置LinearLayout背景色为白色
30 main.setBackgroundColor(0xffffffff);
31 //设置背景亮度为最高
32 LayoutParams lParams=getWindow().getAttributes();
33 lParams.screenBrightness=1.0f;
34 getWindow().setAttributes(lParams);
35 //设置背景常亮
36 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
37 }
38
39 @Override
40 //屏幕的触摸事件
41 public boolean onTouchEvent(MotionEvent event) {
42 // 只有在按下的时候才响应事件,不加这一句,在手指离开屏幕的时候还会响应一次事件,总共两次
43 if (event.getAction()==MotionEvent.ACTION_DOWN) {
44 //定义一个颜色选择对话框
45 ColorPickerDialog cDialog=new ColorPickerDialog(RadioButtontestActivity.this, new OnColorChangedListener() {
46
47 @Override
48 public void colorChanged(int color) {
49 // 当颜色改变的时候,改变屏幕背景色,即为灯光颜色
50 main.setBackgroundColor(color);
51 }
52 }, 0xFFFFFFFF);
53 cDialog.show();
54 }
55 return super.onTouchEvent(event);
56 }
57
58 }

上面的代码里面用到了一个ColorPickerDialog,这个可以在android的sdk目录下找到比如我的是在“D:\android-sdk-windows\samples\android-7\ApiDemos\src\com\example\android\apis\graphics\ColorPickerDialog.java”,原版本是不带黑色和白色的,我修改了一下,现在可以了。代码如下,修改部分做了说明,

View Code
  1 /*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.yyj.Lighter;
18
19 import android.os.Bundle;
20 import android.app.Dialog;
21 import android.content.Context;
22 import android.graphics.*;
23 import android.view.MotionEvent;
24 import android.view.View;
25
26 public class ColorPickerDialog extends Dialog {
27
28 public interface OnColorChangedListener {
29 void colorChanged(int color);
30 }
31
32 private OnColorChangedListener mListener;
33 private int mInitialColor;
34
35 private static class ColorPickerView extends View {
36 private Paint mPaint;
37 private Paint mCenterPaint;
38 private final int[] mColors;
39 private OnColorChangedListener mListener;
40
41 ColorPickerView(Context c, OnColorChangedListener l, int color) {
42 super(c);
43 mListener = l;
44 /*mColors = new int[] {
45 0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
46 0xFFFFFF00, 0xFFFF0000
47 };*/
48 //此处为修改部分
49 mColors = new int[] {
50 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF,0xFFFF0000, 0xFFFF00FF,
51 0xFFFFFF00, 0xFFFF0000, 0xFFFFFFFF
52 };
53 Shader s = new SweepGradient(0, 0, mColors, null);
54
55 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
56 mPaint.setShader(s);
57 mPaint.setStyle(Paint.Style.STROKE);
58 mPaint.setStrokeWidth(50);
59
60 mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
61 mCenterPaint.setColor(color);
62 mCenterPaint.setStrokeWidth(5);
63 }
64
65 private boolean mTrackingCenter;
66 private boolean mHighlightCenter;
67
68 @Override
69 protected void onDraw(Canvas canvas) {
70 float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
71
72 canvas.translate(CENTER_X, CENTER_X);
73
74 canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
75 canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
76
77 if (mTrackingCenter) {
78 int c = mCenterPaint.getColor();
79 mCenterPaint.setStyle(Paint.Style.STROKE);
80
81 if (mHighlightCenter) {
82 mCenterPaint.setAlpha(0xFF);
83 } else {
84 mCenterPaint.setAlpha(0x80);
85 }
86 canvas.drawCircle(0, 0,
87 CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
88 mCenterPaint);
89
90 mCenterPaint.setStyle(Paint.Style.FILL);
91 mCenterPaint.setColor(c);
92 }
93 }
94
95 @Override
96 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
97 setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
98 }
99
100 private static final int CENTER_X = 120;
101 private static final int CENTER_Y = 120;
102 private static final int CENTER_RADIUS = 32;
103
104 private int floatToByte(float x) {
105 int n = java.lang.Math.round(x);
106 return n;
107 }
108 private int pinToByte(int n) {
109 if (n < 0) {
110 n = 0;
111 } else if (n > 255) {
112 n = 255;
113 }
114 return n;
115 }
116
117 private int ave(int s, int d, float p) {
118 return s + java.lang.Math.round(p * (d - s));
119 }
120
121 private int interpColor(int colors[], float unit) {
122 if (unit <= 0) {
123 return colors[0];
124 }
125 if (unit >= 1) {
126 return colors[colors.length - 1];
127 }
128
129 float p = unit * (colors.length - 1);
130 int i = (int)p;
131 p -= i;
132
133 // now p is just the fractional part [0...1) and i is the index
134 int c0 = colors[i];
135 int c1 = colors[i+1];
136 int a = ave(Color.alpha(c0), Color.alpha(c1), p);
137 int r = ave(Color.red(c0), Color.red(c1), p);
138 int g = ave(Color.green(c0), Color.green(c1), p);
139 int b = ave(Color.blue(c0), Color.blue(c1), p);
140
141 return Color.argb(a, r, g, b);
142 }
143
144 private int rotateColor(int color, float rad) {
145 float deg = rad * 180 / 3.1415927f;
146 int r = Color.red(color);
147 int g = Color.green(color);
148 int b = Color.blue(color);
149
150 ColorMatrix cm = new ColorMatrix();
151 ColorMatrix tmp = new ColorMatrix();
152
153 cm.setRGB2YUV();
154 tmp.setRotate(0, deg);
155 cm.postConcat(tmp);
156 tmp.setYUV2RGB();
157 cm.postConcat(tmp);
158
159 final float[] a = cm.getArray();
160
161 int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
162 int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
163 int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
164
165 return Color.argb(Color.alpha(color), pinToByte(ir),
166 pinToByte(ig), pinToByte(ib));
167 }
168
169 private static final float PI = 3.1415926f;
170
171 @Override
172 public boolean onTouchEvent(MotionEvent event) {
173 float x = event.getX() - CENTER_X;
174 float y = event.getY() - CENTER_Y;
175 boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
176
177 switch (event.getAction()) {
178 case MotionEvent.ACTION_DOWN:
179 mTrackingCenter = inCenter;
180 if (inCenter) {
181 mHighlightCenter = true;
182 invalidate();
183 break;
184 }
185 case MotionEvent.ACTION_MOVE:
186 if (mTrackingCenter) {
187 if (mHighlightCenter != inCenter) {
188 mHighlightCenter = inCenter;
189 invalidate();
190 }
191 } else {
192 float angle = (float)java.lang.Math.atan2(y, x);
193 // need to turn angle [-PI ... PI] into unit [0....1]
194 float unit = angle/(2*PI);
195 if (unit < 0) {
196 unit += 1;
197 }
198 mCenterPaint.setColor(interpColor(mColors, unit));
199 invalidate();
200 }
201 break;
202 case MotionEvent.ACTION_UP:
203 if (mTrackingCenter) {
204 if (inCenter) {
205 mListener.colorChanged(mCenterPaint.getColor());
206 }
207 mTrackingCenter = false; // so we draw w/o halo
208 invalidate();
209 }
210 break;
211 }
212 return true;
213 }
214 }
215
216 public ColorPickerDialog(Context context,
217 OnColorChangedListener listener,
218 int initialColor) {
219 super(context);
220
221 mListener = listener;
222 mInitialColor = initialColor;
223 }
224
225 @Override
226 protected void onCreate(Bundle savedInstanceState) {
227 super.onCreate(savedInstanceState);
228 OnColorChangedListener l = new OnColorChangedListener() {
229 public void colorChanged(int color) {
230 mListener.colorChanged(color);
231 dismiss();
232 }
233 };
234
235 setContentView(new ColorPickerView(getContext(), l, mInitialColor));
236 setTitle("Pick a Color");
237 }
238 }

用屏幕照明到这里就结束了,最后面提供源代码的下载。

用闪光灯照明,我在网上着了代码,因为我的手机没有闪光灯,所以贴上来,不确定是不是能用,修改以后的后台代码如下,被我改成了智能选择的,有闪光灯就用闪光灯,没有再用屏幕

 1 package com.yyj.Lighter;
2
3 import com.yyj.Lighter.ColorPickerDialog.OnColorChangedListener;
4 import android.app.Activity;
5 import android.content.Context;
6 import android.content.pm.FeatureInfo;
7 import android.content.pm.PackageManager;
8 import android.hardware.Camera;
9 import android.os.Bundle;
10 import android.view.MotionEvent;
11 import android.view.Window;
12 import android.view.WindowManager;
13 import android.view.WindowManager.LayoutParams;
14 import android.widget.LinearLayout;
15 import android.widget.Toast;
16
17 import com.yyj.Lighter.R;
18
19 public class LighterActivity extends Activity {
20 /** Called when the activity is first created. */
21 LinearLayout main;
22 boolean hasFlashLight=false;
23 Camera camera;
24 @Override
25 public void onCreate(Bundle savedInstanceState) {
26 super.onCreate(savedInstanceState);
27
28 //设置无标题
29 requestWindowFeature(Window.FEATURE_NO_TITLE);
30 //设置全屏
31 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
32 setContentView(R.layout.main);
33 //以下代码判断手机是否带闪光灯
34 FeatureInfo[] feature=LighterActivity.this.getPackageManager().getSystemAvailableFeatures();
35 for (FeatureInfo featureInfo : feature) {
36 if (PackageManager.FEATURE_CAMERA_FLASH.equals(featureInfo.name)) {
37 hasFlashLight=true;
38 break;
39 }
40 }
41 //带闪光灯
42 if(hasFlashLight) {
43 camera=Camera.open();
44 Camera.Parameters parameters=camera.getParameters();
45 parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
46 parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
47 camera.setParameters(parameters);
48 } else {
49 Toast.makeText(LighterActivity.this, "不支持闪光灯,改用屏幕照明。", Toast.LENGTH_LONG).show();
50 main=(LinearLayout)findViewById(R.id.main);
51 //设置背景色为白色
52 main.setBackgroundColor(0xFFFFFFFF);
53 //设置背景亮度为最高
54 LayoutParams lParams=getWindow().getAttributes();
55 lParams.screenBrightness=1.0f;
56 getWindow().setAttributes(lParams);
57 //设置背景常亮
58 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
59 }
60 }
61
62 @Override
63 public boolean onTouchEvent(MotionEvent event) {
64 if (event.getAction()==MotionEvent.ACTION_DOWN) {
65 if (!hasFlashLight) {
66 ColorPickerDialog cDialog=new ColorPickerDialog(LighterActivity.this, new OnColorChangedListener() {
67
68 public void colorChanged(int color) {
69 main.setBackgroundColor(color);
70 }
71 }, 0xFFFFFFFF);
72 cDialog.setCanceledOnTouchOutside(true);
73 cDialog.show();
74 }
75 }
76 return super.onTouchEvent(event);
77 }
78
79
80 @Override
81 protected void onDestroy() {
82 //最后释放Camara对象
83 if (hasFlashLight) {
84 Camera.Parameters parameters=camera.getParameters();
85 parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
86 camera.setParameters(parameters);
87 camera.release();
88 }
89 super.onDestroy();
90 }
91 }

用闪光灯需要在AndroidManifest.xml文件里面定义权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package
="com.yyj.Lighter"
android:versionCode
="1"
android:versionName
="1.0" >

<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:icon="@drawable/ic_launcher"
android:label
="@string/app_name" >
<activity
android:name=".LighterActivity"
android:label
="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

好了最后附上安装文件和源码。两个版本:

1.屏幕照明,安装文件 Light.apk,源文件下载Lighter1.zip,这个确定能用。

2.闪光灯照明,安装文件 Light2.apk,源文件下载Lighter2.zip,这个不确定是否正常运行,反正我的没有闪光灯,效果和第一个一样。有闪光灯的哥们帮忙测试下,谢谢了

最后说一句,上面两个安装包可能会冲突,安装不成功,先删除另一个。

最后来几张截图

Android开发四:插曲1--做一个安卓手电筒_第1张图片 Android开发四:插曲1--做一个安卓手电筒_第2张图片Android开发四:插曲1--做一个安卓手电筒_第3张图片



你可能感兴趣的:(Android开发)