免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2292 | 回复: 1
打印 上一主题 下一主题

Android开发四:插曲1--做一个安卓手电筒 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-25 19:57 |只看该作者 |倒序浏览
Android开发四:插曲1--做一个安卓手电筒











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

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

先说用屏幕照明的,思路是把屏幕设置成全屏的,然后亮度跳成最高,设置保持常亮。然后可以加上一个颜色选择对话框,能让用户选择灯光颜色就行了,实现起来不太麻烦。先说布局文件,特别简单,就是一个LinearLayout。代码如下
  1. <?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>
  2. 复制代码
复制代码
这个和以前用的布局有的差别,我给LinearLayout加了一个id,这个id在代码里面要用到。
然后下面是后台的代码,注释的已经很清楚了
  1. 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 }
  2. 复制代码
复制代码
上面的代码里面用到了一个ColorPickerDialog,这个可以在android的sdk目录下找到比如我的是在“D:\android-sdk-windows\samples\android-7\ApiDemos\src\com\example\android\apis\graphics\ColorPickerDialog.java”,原版本是不带黑色和白色的,我修改了一下,现在可以了。代码如下,修改部分做了说明,

View Code
  1. 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 }
  2. 复制代码
复制代码
用屏幕照明到这里就结束了,最后面提供源代码的下载。

用闪光灯照明,我在网上着了代码,因为我的手机没有闪光灯,所以贴上来,不确定是不是能用,修改以后的后台代码如下,被我改成了智能选择的,有闪光灯就用闪光灯,没有再用屏幕
  1. 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 }
  2. 复制代码
复制代码
用闪光灯需要在AndroidManifest.xml文件里面定义权限
  1. <?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>
  2. 复制代码
复制代码
好了最后附上安装文件和源码。两个版本:

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

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

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

论坛徽章:
0
2 [报告]
发表于 2012-02-25 19:57 |只看该作者
谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP