Android传感器简介
最近单位项目遇到了摇一摇功能,正好把以前的笔记翻出来,整合到一起,发个文章,来吧,互相伤害吧.
<br />
本文代码已上传至Github:https://github.com/Xxxxxxyk/SensorDev
<br />
你真的了解我们日常使用的手机么? 平常你在玩微信摇一摇,手电筒,计步器的时候有没有想过这些是怎么实现的呢?其实这些都归功于手机内部的各种硬件传感器.
认识传感器
在我们开始玩传感器之前,我们先来看下我们的手机中都有什么传感器.
//获取手机基本状态及所有传感器
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hardlist);
TextView tv_brand = (TextView) findViewById(R.id.tv_brand);
//手机号码不一定能获取到
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
tv_brand.setText("品牌: " + Build.BRAND + "\n" + "型号: " + Build.MODEL + "\n" + "Android版本: "
+ android.os.Build.VERSION.RELEASE + "\n" + "IMEI: " + tm.getDeviceId()
+ "\n" + "IMSI: " + tm.getSubscriberId() + "\n" + "手机号码: " + tm.getLine1Number() + "\n"
+ "运营商: " + tm.getSimOperatorName() + "\n");
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> allSensors = sm.getSensorList(Sensor.TYPE_ALL);// 获得传感器列表
RecyclerView rl_list = (RecyclerView) findViewById(R.id.rv_list);
rl_list.setLayoutManager(new LinearLayoutManager(this));
rl_list.setAdapter(new SensorAdapter(this,allSensors));
}
适配器:
public class SensorAdapter extends RecyclerView.Adapter<SensorAdapter.SensorViewHolder> {
private final Context context;
private final List<Sensor> sensors;
public SensorAdapter(Context context, List<Sensor> sensors) {
this.context = context;
this.sensors = sensors;
}
@Override
public SensorViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
SensorViewHolder viewHolder = new SensorViewHolder(LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, null));
return viewHolder;
}
@Override
public void onBindViewHolder(SensorViewHolder holder, int position) {
holder.mTv_text.setText("类型:" + getChineseName(sensors.get(position).getType()) + "\n" + "设备名称:" + sensors.get(position).getName() + "\n设备版本" + sensors.get(position).getVersion() + "\n");
}
@Override
public int getItemCount() {
return sensors == null ? 0 : sensors.size();
}
class SensorViewHolder extends RecyclerView.ViewHolder {
private final TextView mTv_text;
public SensorViewHolder(View itemView) {
super(itemView);
mTv_text = (TextView) itemView.findViewById(android.R.id.text1);
}
}
public String getChineseName(int type) {
switch (type) {
case Sensor.TYPE_ACCELEROMETER:
return "加速度传感器";
case Sensor.TYPE_GYROSCOPE:
return "陀螺仪传感器";
case Sensor.TYPE_LIGHT:
return "环境光线传感器";
case Sensor.TYPE_MAGNETIC_FIELD:
return "电磁场传感器";
case Sensor.TYPE_ORIENTATION:
return "方向传感器";
case Sensor.TYPE_PRESSURE:
return "压力传感器";
case Sensor.TYPE_PROXIMITY:
return "距离传感器";
case Sensor.TYPE_TEMPERATURE:
return "温度传感器";
case Sensor.TYPE_GRAVITY:
return "重场传感器";
case Sensor.TYPE_LINEAR_ACCELERATION:
return "线性加速度传感器";
case Sensor.TYPE_ROTATION_VECTOR:
return "旋转矢量传感器";
case Sensor.TYPE_RELATIVE_HUMIDITY:
return "湿度传感器";
case Sensor.TYPE_AMBIENT_TEMPERATURE:
return "温度传感器";
case Sensor.TYPE_GAME_ROTATION_VECTOR:
return "游戏旋转矢量传感器";
case Sensor.TYPE_STEP_COUNTER:
return "计步器";
case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
return "地磁旋转矢量传感器";
case Sensor.TYPE_SIGNIFICANT_MOTION:
return "特殊动作触发传感器";
default:
return "未知传感器";
}
}
}
写好之后我们来运行试一下:
楼主用自己手机进行测试的,华为荣耀8(吐槽一句,真难用),基本所有的传感器都被识别了,没有识别的两个一个是霍尔传感器(HALL),另一个是电话传感器(PhoneCall).
传感器开发
震动传感器
官方文档:https://developer.android.google.cn/reference/android/os/Vibrator.html
震动传感器,顾名思义,手机振动全靠它,那么我们如何控制我们的手机震动呢,上代码:
public class VibratorUtils {
private final Vibrator mVibrator;
//震动传感器
public VibratorUtils(Context context){
//获取系统服务
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
}
//震动,time为震动时间
public void shock(long time){
mVibrator.vibrate(time);
}
}
很简单,两句代码搞定,调用时只需要传入时间即可,单位是s.(如果我们把时间调成好多好多秒,会不会有什么神奇的事情发生呢,我这么纯洁肯定不知道)
闪光灯
官方文档:https://developer.android.google.cn/reference/android/hardware/camera2/CameraManager.html
好了好了,不开车,接下来我们看看我们平常使用的手电筒是怎么实现的,需要注意的是,以下代码只运行在API21以上,并且你有闪光灯:
public class FlashLampUtils {
//闪光灯
private final CameraManager mSystemService;
public FlashLampUtils(Context context) {
//获取系统服务
mSystemService = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
}
@TargetApi(Build.VERSION_CODES.M)
public void openLamp(){
if(!isLOLLIPOP()){
return;
}
try {
mSystemService.setTorchMode("0", true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@TargetApi(Build.VERSION_CODES.M)
public void closeLamp(){
if(!isLOLLIPOP()){
return;
}
try {
mSystemService.setTorchMode("0", false);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 判断Android系统版本
*
* @return boolean
*/
private boolean isLOLLIPOP() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return true;
} else {
return false;
}
}
}
只需要调用,闪光灯就可以亮起来了,除此之外,很多手机中都有手电筒的SOS功能,其实也非常简单,大家可以自行尝试.
指纹传感器
官方文档:https://developer.android.google.cn/reference/android/support/v4/hardware/fingerprint/package-summary.html
Google在API 23之后在官方API中加入了指纹API,方便用户进行指纹的一系列操作,那么我们怎么给我们自己的APP加入指纹功能呢,代码如下:
public class FingerPrintUtils {
//指纹传感器
public static final String TAG = "惜梦哥哥_";
private final FingerprintManagerCompat mManagerCompat;
public FingerPrintUtils(Context context) {
mManagerCompat = FingerprintManagerCompat.from(context);
}
public void checkFingerPrint(){
/**
* 检查是否支持指纹识别
*/
if(mManagerCompat.hasEnrolledFingerprints()){
mManagerCompat.authenticate(null, 0, null, new FingerprintManagerCompat.AuthenticationCallback() {
/**
* 出现错误回调,多次尝试失败也会调用
*/
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
Log.e(TAG,errMsgId + "--------" + errString.toString());
}
/**
* 错误信息提示
*/
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Log.e(TAG,helpMsgId + "--------" + helpString.toString());
}
/**
* 当验证的指纹成功时会回调此函数,然后取消监听
*/
@Override
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
Log.e(TAG,"验证成功");
}
/**
* 指纹验证失败
*/
@Override
public void onAuthenticationFailed() {
Log.e(TAG,"验证失败");;
}
}, null);
};
}
}
这里验证的指纹就是你在系统中设置的指纹,可以在回调中进行不同操作.
光线传感器
官方文档:https://developer.android.google.cn/reference/android/hardware/Sensor.html#TYPE_LIGHT
光线传感器是用来感应手机周围的亮度的,我们的手机上的自动调整亮度功能离不开这个传感器,让我们来看下你的周围的亮度有多少吧
public class LightUtils {
private final Sensor mDefaultSensor;
private final SensorManager mSystemService;
//光线传感器
public LightUtils(Context context) {
mSystemService = (SensorManager) context.getSystemService(SENSOR_SERVICE);
mDefaultSensor = mSystemService.getDefaultSensor(Sensor.TYPE_LIGHT);
}
public void getLightNum(SensorEventListener sensorEventListener) {
mSystemService.registerListener(sensorEventListener, mDefaultSensor, SensorManager.SENSOR_DELAY_UI);
}
}
调用时需要传入SensorEventListener 对象,这个对象中有两个方法,当传感器的值发生变化时,会调用onSensorChanged方法,当传感器的精度发生变化时,会调用onAccuracyChanged,这里我们只需要在onSensorChanged方法中处理我们的操作就可以
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
mBtn_light.setText("当前亮度" + sensorEvent.values[0]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
加速传感器
官方文档:https://developer.android.google.cn/reference/android/hardware/Sensor.html#TYPE_ACCELEROMETER
加速传感器,就是我们平常进行摇(YUE)一(PAO)摇时采用的传感器,手动脸红.
//SensorManager代表了各类传感器的集合
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
if (mSensorManager != null) {
//加速传感器
mMSensorManagerDefaultSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (mMSensorManagerDefaultSensor != null) {
mSensorManager.registerListener(this, mMSensorManagerDefaultSensor, SensorManager.SENSOR_DELAY_UI);
}
}
加载完成传感器之后在回调方法中进行操作
private static final int UPTATE_INTERVAL_TIME = 50;
//灵敏度调节
private static final int SPEED_SHRESHOLD = 30;
private long lastUpdateTime;
private float lastX;
private float lastY;
private float lastZ;
........
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
long currentUpdateTime = System.currentTimeMillis();
long timeInterval = currentUpdateTime - lastUpdateTime;
if (timeInterval < UPTATE_INTERVAL_TIME) {
return;
}
lastUpdateTime = currentUpdateTime;
// 传感器信息改变时执行该方法
float[] values = sensorEvent.values;
float x = values[0]; // x轴方向的重力加速度,向右为正
float y = values[1]; // y轴方向的重力加速度,向前为正
float z = values[2]; // z轴方向的重力加速度,向上为正
float deltaX = x - lastX;
float deltaY = y - lastY;
float deltaZ = z - lastZ;
lastX = x;
lastY = y;
lastZ = z;
double speed = (Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / timeInterval) * 100;
if (speed >= SPEED_SHRESHOLD) {
mVibrator.vibrate(300);
Toast.makeText(this, "摇一摇震动", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
这里有个坑,大家要注意啦:
注册监听器的时候需要在onStart方法中注册,取消监听器需在onPause方法中取消,原因是因为Activity的生命周期问题,避免按Home键之后感应依旧存在,造成不必要的Bug.
@Override
protected void onStart() {
super.onStart();
shake();
}
@Override
protected void onPause() {
if (mSensorManager != null) {
mSensorManager.unregisterListener(this);
}
super.onPause();
}
结尾
好了,本次就介绍这个5个传感器吧,希望大家可以尝试一下,因为这个真的很好玩哟.最后再推荐一首歌,英文歌,但是真的很好听: