- 论坛徽章:
- 0
|
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 @Override18 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的id28 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 @Override40 //屏幕的触摸事件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 @Override48 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 index134 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 @Override172 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 halo208 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 @Override226 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 @Override25 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 @Override63 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 @Override81 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,这个不确定是否正常运行,反正我的没有闪光灯,效果和第一个一样。有闪光灯的哥们帮忙测试下,谢谢了
最后说一句,上面两个安装包可能会冲突,安装不成功,先删除另一个。
|
|