一、在Android开发中,有时我们需要获知设备所在环境的光线强弱情况,当然这需要我们设备拥有光线传感器

下面是我简单封装的一个光线传感器管理类,主要提供了3个方法:

1.start():启动,在获取光照强度前调用。

2.stop():停止,在不再需要获取光照强度后调用。

3.getLux():获取光照强度,单位为勒克斯(lux)。

如果你需要额外的一些方法,可以根据返回的光照强度自行添加。下面是整个LightSensorManager类

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;public class LightSensorManager {private static final boolean DEBUG = true;private static final String TAG = "LightSensor";private static LightSensorManager instance;private SensorManager mSensorManager;private LightSensorListener mLightSensorListener;private boolean mHasStarted = false;private LightSensorManager() {}public static LightSensorManager getInstance() {if (instance == null) {instance = new LightSensorManager();}return instance;}public void start(Context context) {if (mHasStarted) {return;}mHasStarted = true;mSensorManager = (SensorManager) context.getApplicationContext().getSystemService(Context.SENSOR_SERVICE);Sensor lightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); // 获取光线传感器if (lightSensor != null) { // 光线传感器存在时mLightSensorListener = new LightSensorListener();mSensorManager.registerListener(mLightSensorListener, lightSensor,SensorManager.SENSOR_DELAY_NORMAL); // 注册事件监听}}public void stop() {if (!mHasStarted || mSensorManager == null) {return;}mHasStarted = false;mSensorManager.unregisterListener(mLightSensorListener);}/*** 获取光线强度*/public float getLux() {if (mLightSensorListener != null) {return mLightSensorListener.lux;}return -1.0f; // 默认返回-1,表示设备无光线传感器或者为调用start()方法}private class LightSensorListener implements SensorEventListener {private float lux; // 光线强度public void onAccuracyChanged(Sensor sensor, int accuracy) {}public void onSensorChanged(SensorEvent event) {if (event.sensor.getType() == Sensor.TYPE_LIGHT) {// 获取光线强度lux = event.values[0];if (DEBUG) {Log.d(TAG, "lux : " + lux);}}}}}

对于这个光线强度的值。越暗数值越低,最低应该是0,在白天室内经测试有40-60左右,室外明亮地方有300-400左右,仅供参考。

二、仿微信扫一扫二维码放大和光线检测

1、CaptureActivity.java修改:

注册广播来接收光线变化,从而显示或隐藏手机上的手电筒按钮

IntentFilter mFilter = new IntentFilter("lightchanged");
LightListenReceiver mReceiver = new LightListenReceiver();
registerReceiver(mReceiver, mFilter);class LightListenReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if ("lightchanged".equals(action)) {if (Constant.isWeakLight) {// 光线太暗}else {// 光线正常}}}
}

2、在Constant.java中添加:判断当前光线是否是弱光线

 public static boolean isWeakLight = false;

3、CameraManager.java中添加如下代码:

 public Camera getCamera() {return camera;}

4、DecodeHandler.java:

package com.wwwarehouse.common.tripartite_widget.zxing;import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.wwwarehouse.common.R;
import com.wwwarehouse.common.activity.CaptureActivity;
import com.wwwarehouse.common.constant.Constant;import java.text.DecimalFormat;
import java.util.Map;final class DecodeHandler extends Handler {private static final String TAG = DecodeHandler.class.getSimpleName();private final CaptureActivity activity;private final MultiFormatReader multiFormatReader;private boolean running = true;private int frameCount;private long intervalTime;private static final long INTERVAL = 30 * 1000L;private boolean isResetTime = true;private Rect frameRect;DecodeHandler(Activity activity, Map<DecodeHintType, Object> hints) {multiFormatReader = new MultiFormatReader();multiFormatReader.setHints(hints);this.activity = (CaptureActivity)activity;frameRect = CameraManager.get().getFramingRect();}@Overridepublic void handleMessage(Message message) {if (!running) {return;}if (message.what == R.id.decode) {decode((byte[]) message.obj, message.arg1, message.arg2);} else if (message.what == R.id.quit) {running = false;Looper.myLooper().quit();}}private void decode(byte[] data, int width, int height) {byte[] rotatedData = new byte[data.length];for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++)rotatedData[x * height + height - y - 1] = data[x + y * width];}frameCount++;//丢弃前2帧并每隔2帧分析下预览帧color值if (frameCount > 2 && frameCount % 2 == 0) {analysisBitmapColor(data, width, height);}long start = System.currentTimeMillis();if (isResetTime) {intervalTime = System.currentTimeMillis();isResetTime = false;}Result rawResult = null;final PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, height, width);if (source != null) {BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));try {rawResult = multiFormatReader.decodeWithState(bitmap);} catch (ReaderException re) {// continue} finally {multiFormatReader.reset();}}final Handler handler = activity.getHandler();if (rawResult != null) {// Don't log the barcode contents for security.long end = System.currentTimeMillis();Log.d(TAG, "Found barcode in " + (end - start) + " ms");if (handler != null) {float point1X = rawResult.getResultPoints()[0].getX();float point1Y = rawResult.getResultPoints()[0].getY();float point2X = rawResult.getResultPoints()[1].getX();float point2Y = rawResult.getResultPoints()[1].getY();int len = (int) Math.sqrt(Math.abs(point1X - point2X) * Math.abs(point1X - point2X) + Math.abs(point1Y - point2Y) * Math.abs(point1Y - point2Y));if (frameRect != null) {int frameWidth = frameRect.right - frameRect.left;Camera camera = CameraManager.get().getCamera();Camera.Parameters parameters = camera.getParameters();final int maxZoom = parameters.getMaxZoom();int zoom = parameters.getZoom();if (parameters.isZoomSupported()) {if (len <= frameWidth / 4) {if (zoom == 0) {zoom = maxZoom / 3;} else {zoom = zoom + 10;}if (zoom > maxZoom) {zoom = maxZoom;}parameters.setZoom(zoom);camera.setParameters(parameters);final Result finalRawResult = rawResult;postDelayed(new Runnable() {@Overridepublic void run() {Message message = Message.obtain(handler, R.id.decode_succeeded, finalRawResult);Bundle bundle = new Bundle();bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());message.setData(bundle);message.sendToTarget();}}, 1000);} else {Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);Bundle bundle = new Bundle();bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());message.setData(bundle);message.sendToTarget();}}} else {Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);Bundle bundle = new Bundle();bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());message.setData(bundle);message.sendToTarget();}}} else {if (handler != null) {Message message = Message.obtain(handler, R.id.decode_failed);message.sendToTarget();}}}private void analysisBitmapColor(byte[] data, int width, int height) {int[] rgb = decodeYUV420SP(data, width, height);Bitmap bmp = null;if (null != frameRect) {//取矩形扫描框frameRect的2分之一创建为bitmap来分析bmp = Bitmap.createBitmap(rgb, frameRect.left + (frameRect.right - frameRect.left) / 4, frameRect.width() / 2, frameRect.width() / 2, frameRect.height() / 2, Bitmap.Config.ARGB_4444);}if (bmp != null) {float color = getAverageColor(bmp);DecimalFormat decimalFormat1 = new DecimalFormat("0.00");String percent = decimalFormat1.format(color / -16777216);float floatPercent = Float.parseFloat(percent);Log.e(TAG, " color= " + color + " floatPercent= " + floatPercent + " bmp width= " + bmp.getWidth() + " bmp height= " + bmp.getHeight());Constant.isWeakLight = (color == -16777216 || (floatPercent >= 0.85 && floatPercent <= 1.00));bmp.recycle();}}private int[] decodeYUV420SP(byte[] yuv420sp, int width, int height) {final int frameSize = width * height;int rgb[] = new int[width * height];for (int j = 0, yp = 0; j < height; j++) {int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;for (int i = 0; i < width; i++, yp++) {int y = (0xff & ((int) yuv420sp[yp])) - 16;if (y < 0) y = 0;if ((i & 1) == 0) {v = (0xff & yuv420sp[uvp++]) - 128;u = (0xff & yuv420sp[uvp++]) - 128;}int y1192 = 1192 * y;int r = (y1192 + 1634 * v);int g = (y1192 - 833 * v - 400 * u);int b = (y1192 + 2066 * u);if (r < 0) r = 0;else if (r > 262143) r = 262143;if (g < 0) g = 0;else if (g > 262143) g = 262143;if (b < 0) b = 0;else if (b > 262143) b = 262143;rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) &0xff00) | ((b >> 10) & 0xff);}}return rgb;}private int getAverageColor(Bitmap bitmap) {int redBucket = 0;int greenBucket = 0;int blueBucket = 0;int pixelCount = 0;for (int y = 0; y < bitmap.getHeight(); y++) {for (int x = 0; x < bitmap.getWidth(); x++) {int c = bitmap.getPixel(x, y);pixelCount++;redBucket += Color.red(c);greenBucket += Color.green(c);blueBucket += Color.blue(c);}}int averageColor = Color.rgb(redBucket / pixelCount, greenBucket/ pixelCount, blueBucket / pixelCount);return averageColor;}
}

5、ViewFinderView.java中的onDraw()最后面加入:

  Context mContext;@Overridepublic void onDraw(Canvas canvas) {...Intent it = new Intent("lightchanged");mContext.sendBroadcast(it);}

光线传感器工具类,和仿微信扫一扫预览条码放大和光线检测相关推荐

  1. java工具类-java仿微信九宫格头像

    创建Utils类 ImageUtil package com.mrd.utils;import javax.imageio.ImageIO; import java.awt.Color; import ...

  2. 仿微信朋友圈图片预览自定义View

    1.先来看看效果 2.使用方法 在xml中添加如下代码: <?xml version="1.0" encoding="utf-8"?> <Fr ...

  3. 微信小程序开发工具能正常请求后台数据,手机预览请求失败

    微信小程序开发工具能正常请求后台数据,手机预览请求失败 问题描述 微信开发者工具调试完想用手机预览效果,结果发现凡是后台请求都失败. 原因分析 可能的原因有三个: 微信开发者工具详情里的本地设置,没有 ...

  4. 小红书多图剪裁+微信图片选择器+大图预览+图片剪裁等等 相册

    最近发现一个挺不错的开源库,推荐给大家. 简介:小红书多图剪裁+微信图片选择器+大图预览+图片剪裁(支持圆形剪裁和镂空剪裁),已适配androidQ,借鉴并升级matisse加载内核!超强定制性可轻松 ...

  5. 微信小程序上传图片 预览 删除

    微信小程序上传图片 预览 删除 ①.wxml<view class='footerEditOne'><view wx:for="{{src}}" wx:key=' ...

  6. 使用微信内置浏览器预览图片

    在微信H5开发中预览图片,可以使用其他的一些图片预览插件,但是这样却不能把其中的某张图片发送给好友.对于 这种情况可以使用微信内置浏览器图片预览功能,就可以解决这个问题.不说废话直接看代码: 1.首先 ...

  7. 微信小程序在开发工具上可以编译显示,但是手机预览请求不到数据

    问题描述:在开发者工具调试时状态显示正常,但是上传发布后真机调试发现拉去不了数据,只是空壳! 在模拟器上正常看到请求数据了. ~~~那么然后你肯定想在手机微信上试下,于是你点了导航栏的"预览 ...

  8. 微信小程序手机预览请求不到数据?

    本地开发调试小程序时,用手机预览需要有如下设置: 1.微信开发者工具中,本地设置:不校验安全域名.web-view 域名.TLS 版本以及 HTTPS 证书.这样在有网络请求的时候,就可以访问本地的服 ...

  9. 微信小程序打开预览下载的文件

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 使用 wx.openDocument(obj) 方法预览 wx.downloadFile({url: 'htt ...

最新文章

  1. 【 MATLAB 】信号处理工具箱之 dct 简介及案例分析
  2. ROS系统 C++或Python实现订阅者Subscriber
  3. 微软OCR两层优化提升自然场景下的文字识别精度(模式识别新研究)
  4. Python Pytest装饰器@pytest.mark.parametrize详解
  5. docker 远程连接 文件看不到_Java 开发提升十倍生产力:IDEA 远程一键部署 Spring Boot 到 Docker...
  6. GD2拖动验证码Thinkphp版
  7. I firmly believe
  8. 进销存软件排行榜前十名!
  9. LBP算法,空间金字塔 文献阅读报告《基于差分量化局部二值模式的人脸反欺诈算法研究》
  10. Minecraft forge服务端安装
  11. Windows NT/2000/XP下不用驱动的Ring0代码实现
  12. Unity 模拟鼠标自动点击事件
  13. 站长咪咪网整理的Linux命令大全
  14. python金融衍生品大数据分析豆瓣_Python金融衍生品大数据分析
  15. 【OR】二次规划(1)
  16. 操作系统13章(个人笔记)
  17. 马斯克都不懂的 GraphQL,API 网关又能对其如何理解?
  18. 阿里云国际站和阿里云国内站有什么区别?
  19. openpyxl更改字体类型、字体颜色
  20. 【系统】【winget】从零开始配置一个开发用的 Windows 11 系统的电脑 - winget 代码终端安装软件

热门文章

  1. w3school html 表单
  2. 阿里工作7年,肝到P8就靠这份学习笔记了,已助14个朋友拿到offer
  3. 乐优商场项目day02——总结
  4. A股全市场股票历史行情1分钟高频数据
  5. anaconda 安装第三方库
  6. 计算机考证去哪个软件报名
  7. Spring AOP基础组件 Pointcut
  8. 三, Spark 四种运行环境配置总结
  9. 【FJWC】day1简要题解
  10. matlab lyapunov指数,lyapunov指数matlab