Android传感器开发(上)

作者: 惜梦哥哥_ | 来源:发表于2017-06-28 14:36 被阅读200次

Android传感器简介

最近单位项目遇到了摇一摇功能,正好把以前的笔记翻出来,整合到一起,发个文章,来吧,互相伤害吧.
<br />
本文代码已上传至Github:https://github.com/Xxxxxxyk/SensorDev
<br />
你真的了解我们日常使用的手机么? 平常你在玩微信摇一摇,手电筒,计步器的时候有没有想过这些是怎么实现的呢?其实这些都归功于手机内部的各种硬件传感器.

image.png

认识传感器

在我们开始玩传感器之前,我们先来看下我们的手机中都有什么传感器.

//获取手机基本状态及所有传感器
    @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 "未知传感器";
        }
    }
}

写好之后我们来运行试一下:

Screenshot_2017-06-27-16-07-52.jpg

楼主用自己手机进行测试的,华为荣耀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.(如果我们把时间调成好多好多秒,会不会有什么神奇的事情发生呢,我这么纯洁肯定不知道)

image.png
闪光灯

官方文档: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功能,其实也非常简单,大家可以自行尝试.

image.png
指纹传感器

官方文档: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);
        };
    }
}

这里验证的指纹就是你在系统中设置的指纹,可以在回调中进行不同操作.

image.png
光线传感器

官方文档: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) {

    }
image.png
加速传感器

官方文档: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();
}
image.png

结尾

好了,本次就介绍这个5个传感器吧,希望大家可以尝试一下,因为这个真的很好玩哟.最后再推荐一首歌,英文歌,但是真的很好听:

image.png

相关文章

  • Android传感器应用开发

    Android传感器应用开发 Android系统提供了对传感器的支持,如果手机设备的硬件提供了这些传感器,Andr...

  • Android的传感器开发

    在Android系统中开发传感器应用十分简单,因为Android系统为传感器支持提供了强大的管理服务,同样传感器的...

  • Android传感器开发(上)

    Android传感器简介 最近单位项目遇到了摇一摇功能,正好把以前的笔记翻出来,整合到一起,发个文章,来吧,互相伤...

  • Android 传感器开发详解

    Android 传感器开发详解 传感器 传感器的分类 方向传感器 陀螺仪传感器 磁场传感器 重力传感器 线性加速度...

  • Android传感器

    一.Android的三大类传感器 Android传感器按大方向划分大致有这么三类传感器:动作(Motion)传感器...

  • 传感器

    一.Android的三大类传感器 Android传感器按大方向划分大致有三类传感器:动作(Motion)传感器、环...

  • Android传感器(第一篇)

    Android传感器定义 Android 传感器相关术语微机电传感器(MEMS)MEMS 通常制作在规格很小的硅芯...

  • Android 传感器总结

    最近项目需要各种手机传感器,于是就此来写个总结,以此留痕。在Android开发中,会用到各种传感器,但不一定每个真...

  • 关于Android传感器

    最近项目需要各种手机传感器,于是就此来写个总结,以此留痕。在Android开发中,会用到各种传感器,但不一定每个真...

  • Android开发高级进阶——传感器

    Android系统提供了对传感器的支持,如果手机设备的硬件提供了这些传感器,Android应用可以通过传感器来获取...

网友评论

  • eec1c01d1dc7:写的不错,加油,对于安卓初学者很有帮助

本文标题:Android传感器开发(上)

本文链接:https://www.haomeiwen.com/subject/eyeecxtx.html