zoukankan      html  css  js  c++  java
  • android 传感器类 sensor

    手机所有传感器的列出:

    首先说一下android平台下的11种感应器:
               1. ACCELEROMETER 加速,描述加速度的。
               2.GRAVITY 重力,这个在大家都知道。
               3.GYROSCOPE 陀螺仪,对于物体跌落检测更强大些,开发游戏少了它会有点遗憾的,API Level 9新增的类型。
               4. LIGHT 光线感应器,很多Android手机的屏幕亮度是根据这个感应器的数组自动调节的。
               5. LINEAR_ACCELERATION 线性加速器,API Level 9新增的。
               6. MAGNETIC_FIELD 磁极感应器。
               7. ORIENTATION 方向感应器。
               8. PRESSURE 压力感应器。 
               9. PROXIMITY 距离感应器,对于通话后关闭屏幕背光很有用。
             10. ROTATION_VECTOR 旋转向量,Android 2.3新增的,如果我们过去处理图像会发现这个还是很有用的,不过这里还是对游戏开发起到辅助。
      11. TEMPERATURE 温度感应器,可以获取手机的内部温度,不过和周边的有些差距,毕竟手机内部一般温度比较高。
    复制代码
    package mars.com;
     
    import java.util.List;
     
    import android.app.Activity;
     
    import android.content.Context;
     
    import android.hardware.Sensor;
     
    import android.hardware.SensorManager;
     
    import android.os.Bundle;
     
    import android.view.View;
     
    import android.view.View.OnClickListener;
     
    import android.widget.Button;
     
    import android.widget.TextView;
     
    public class DemoSensorActivity extends Activity {
     
    private Button button;
     
    private TextView show;
     
    private SensorManager sm;
     
    private StringBuffer str;
     
    private List<Sensor> allSensors;
     
    private Sensor s;
     
    @Override
     
    public void onCreate(Bundle savedInstanceState) {
     
      super.onCreate(savedInstanceState);
     
      setContentView(R.layout.main);
     
      button = (Button) findViewById(R.id.button);
     
      show = (TextView) findViewById(R.id.show);
     
      button.setOnClickListener(new ButtonListener());
     
      sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
     
      allSensors = sm.getSensorList(Sensor.TYPE_ALL);// 获得传感器列表
     
    }
     
    class ButtonListener implements OnClickListener {
     
      public void onClick(View v) {
     
       str = new StringBuffer();
     
       str.append("该手机有" + allSensors.size() + "个传感器,分别是:\n");
     
       for (int i = 0; i < allSensors.size(); i++) {
     
        s = allSensors.get(i);
     
        str.append("设备名称:" + s.getName() + "\n");
     
        str.append("设备版本:" + s.getVersion() + "\n");
     
        str.append("通用类型号:" + s.getType() + "\n");
     
        str.append("设备商名称:" + s.getVendor() + "\n");
     
        str.append("传感器功耗:" + s.getPower() + "\n");
     
        str.append("传感器分辨率:" + s.getResolution() + "\n");
     
        str.append("传感器最大量程:" + s.getMaximumRange() + "\n");
     
        switch (s.getType()) {
     
        case Sensor.TYPE_ACCELEROMETER:
     
         str.append(i + "加速度传感器");
     
         break;
     
        case Sensor.TYPE_GYROSCOPE:
     
         str.append(i + "陀螺仪传感器");
     
         break;
     
        case Sensor.TYPE_LIGHT:
     
         str.append(i + "环境光线传感器");
     
         break;
     
        case Sensor.TYPE_MAGNETIC_FIELD:
     
         str.append(i + "电磁场传感器");
     
         break;
     
        case Sensor.TYPE_ORIENTATION:
     
         str.append(i + "方向传感器");
     
         break;
     
        case Sensor.TYPE_PRESSURE:
     
         str.append(i + "压力传感器");
     
         break;
     
        case Sensor.TYPE_PROXIMITY:
     
         str.append(i + "距离传感器");
     
         break;
     
        case Sensor.TYPE_TEMPERATURE:
     
         str.append(i + "温度传感器");
     
         break;
     
        default:
     
         str.append(i + "未知传感器");
     
         break;
     
        }
     
       }
     
       show.setText(str);
     
      }
     
    }
     
    }
     
    复制代码
     
    要善于应用这些资源,今天要说的就是距离感应器。其这个锁频的原理也很简单,就是当有物体靠近距离感应器的时候,会触发事件,然后在事件里面申请设备电源锁,让屏幕处于黑屏出台,然后当物体离开距离感应器,释放设备电源锁,就ok了。下面看看代码
    MainActivity.java  这个类很简单,就是启动一个Service。
    public class MainActivity extends Activity {
     
    /** Called when the activity is first created. */
     
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
     
    setContentView(R.layout.main);
     
    Intent intent = new Intent(MainActivity.this, MyService.class);
    startService(intent);
     
    }
    }

       然后就是MyService.java   主要内容

    public class MyService extends Service {
     
    private SensorManager mManager;
     
    private Sensor mSensor = null;
     
    private SensorEventListener mListener = null;
     
    private PowerManager localPowerManager = null;
    private PowerManager.WakeLock localWakeLock = null;
     
     
    @Override
    public void onCreate() {
     
    //获取系统服务POWER_SERVICE,返回一个PowerManager对象
    localPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    //获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是LogCat里用的Tag
    localWakeLock = this.localPowerManager.newWakeLock(32, "MyPower");
     
    //获取系统服务SENSOR_SERVICE,返回一个SensorManager对象
    mManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    //获取距离感应器对象
    mSensor = mManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    //注册感应器事件
    mListener = new SensorEventListener() {
     
    @Override
    public void onSensorChanged(SensorEvent event) {
     
    float[] its = event.values;
     
    if (its != null
     
    && event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
     
    System.out.println("its[0]:" + its[0]);
     
    //经过测试,当手贴近距离感应器的时候its[0]返回值为0.0,当手离开时返回1.0
    if (its[0] == 0.0) {// 贴近手机
     
    System.out.println("手放上去了...");
     
    if (localWakeLock.isHeld()) {
    return;
    } else
    localWakeLock.acquire();// 申请设备电源锁
     
    } else {// 远离手机
     
    System.out.println("手拿开了...");
     
    if (localWakeLock.isHeld()) {
    return;
    } else
    localWakeLock.setReferenceCounted(false);
    localWakeLock.release(); // 释放设备电源锁
    } }
    }
     
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
     
    }
    };
    }
     
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     
    //注册监听
    mManager.registerListener(mListener, mSensor,
    SensorManager.SENSOR_DELAY_GAME);
     
    return super.onStartCommand(intent, flags, startId);
    }
     
    @Override
    public void onDestroy() {
     
    //取消监听
    mManager.unregisterListener(mListener);
     
    super.onDestroy();
    }
     
    @Override
    public IBinder onBind(Intent intent) {
    return null;
    }
     
    }

      

    AndroidManifest.xml 中需要添加权限
    <uses-permissionandroid:name="android.permission.DEVICE_POWER"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    由于时间原因,我这里只是实现了功能,还有很多要优化的地方,有需要的话自己可以加上。
        优化1:当按下的时候,屏幕会锁住,但是感应器事件依然会触发,也就是说,当你挡住距离感应器,然后再放开,屏幕依然会亮。
         解决方法:当系统锁屏或黑屏会广播两个消息分别是:ACTION_SCREEN_OFFACTION_SCREEN_ON,所以我们可以自己写个BroadcastReceiver来接受这个广播,并且做相应的处理。具体处理方法大家可以在黑屏的时候停止service,然后在屏幕亮后再启动service。或者更简单的定义个boolean变量,黑屏为false,亮的时候为true,然后判断在true的情况下才申请设备电源锁,应该都可以。大概代码如下
    public class MyReceiver extends BroadcastReceiver {
     
    @Override
    public void onReceive(Context context, Intent intent) {
     
    String action = intent.getAction();
     
    if (action.equals("android.intent.action.SCREEN_OFF")) {
     
     
    } else if (action.equals("android.intent.action.SCREEN_ON")) {
     
     
    }
     
    }
     
    }

      

    优化2:实现可以手动关闭和启动service。在MainActivity中可以添加个checkBox,以便开启和停止服务。这个应该很简单就不详细说明了。
    优化3:开机自启动。这个就不说了,网上大把大把的资料。
    最后再讲解下PowerManager这个类。
    PowerManager这个类主要是用来控制电源状态的. 通过使用该类提供的api可以控制电池的待机时间,一般情况下不要使用。如果确实需要使用,那么尽可能的使用最低级别的WakeLocks锁。并且确保使用完后释放它。你可以通过context.getSystemService(Context.POWER_SERVICE)的方式获得PowerManager的实例。在PowerManager中,最主要的newWakeLock方法,SDK源码如下
    /**
    * Get a wake lock at the level of the flags parameter. Call
    * {@link WakeLock#acquire() acquire()} on the object to acquire the
    * wake lock, and {@link WakeLock#release release()} when you are done.
    *
    * {@samplecode
    *PowerManager pm = (PowerManager)mContext.getSystemService(
    * Context.POWER_SERVICE);
    *PowerManager.WakeLock wl = pm.newWakeLock(
    * PowerManager.SCREEN_DIM_WAKE_LOCK
    * | PowerManager.ON_AFTER_RELEASE,
    * TAG);
    *wl.acquire();
    * // ...
    *wl.release();
    * }
    *
    * @param flags Combination of flag values defining the requested behavior of the WakeLock.
    * @param tag Your class name (or other tag) for debugging purposes.
    *
    * @see WakeLock#acquire()
    * @see WakeLock#release()
    */
    public WakeLock newWakeLock(int flags, String tag)
    {
    return new WakeLock(flags, tag);
    }

      这个方法将创建WakeLock对象,通过调用此对象的方法你就可以方便的去控制电源的状态。方法如下:

    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
    wl.acquire();
    屏幕将停留在设定的状态,一般为亮、暗状态
    wl.release();
    释放掉正在运行的cpu或关闭屏幕。

      

    flags参数说明:
                             *                                                   cpu       screen       keyboard                          * PARTIAL_WAKE_LOCK                   on         off             off                          * SCREEN_DIM_WAKE_LOCK            on         dim             off                          * SCREEN_BRIGHT_WAKE_LOCK      on         bright          off                          * FULL_WAKE_LOCK                        on         bright          bright
    如果你持有PARTIAL_WAKE_LOCK锁,不论任何定时器甚至是按下电源按钮,cpu都将继续运行,无法进入休眠状态。除非你释放掉它。其他锁的话,虽然cpu也在运行,但是当用户按下电源按钮时,设备将立刻进入休眠状态。
  • 相关阅读:
    Oracle 提示 用户在线,无法删除的清理方法
    拉格朗日乘子法和KKT条件
    主题模型及其在文本情感分析中的应用
    spring-data-elasticsearch整合elasticsearch
    自然数的K次幂的数列求和
    SVM 简要推导过程
    机器学习中导数最优化方法(基础篇)
    漫谈:机器学习中距离和相似性度量方法
    A geometric interpretation of the covariance matrix
    数据挖掘算法之协同过滤算法
  • 原文地址:https://www.cnblogs.com/crazywenza/p/2891458.html
Copyright © 2011-2022 走看看