zoukankan      html  css  js  c++  java
  • Android对方向感应器的封装调用

     Android自动的SensorManager使用起来已经很方便,但由于一些情况我们希望对其中的功能进行封装:

    • 只使用个别的sensor,功能相对单一
    • 要对sensor返回的raw data进行算法处理方可使用
    • 程序中多处频繁调用禁用sensor的数据

    由于项目需要在很多页面调用手机的方向信息,故而对sensor的方向感应器进行简单的封装,源码如下:

    package com.weicheche.android.service;
    
    import java.util.ArrayList;
    import com.****.android.bean.ApplicationContext;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.Handler;
    import android.os.SystemClock;
    
    /**
     * 
     * @ClassName: OrientationService 
     * @Description: TODO(对android SDk自带的方向感应器进行封装) 
     * @author xuyong yxy8023@gmail.com   
     * @date  2014年7月14日  上午2:24:10
     */
    public class OrientationService implements SensorEventListener {
    
        /*
         * 对于想要监听方向变化的类,需要继承实现这个接口
         */
        public static abstract interface OrientationListener{
            public abstract void onOrientationChanged(float orientatoin);
        }
        
        protected final Handler mHandler = new Handler();
        private SensorManager sensorManager;
        private Sensor mOrientationSensor;
        private float mTargetDirection = 0;
        private ArrayList<OrientationListener> listenerList = new ArrayList<OrientationListener>();
        private long delayMillis = 20;
        
        public OrientationService() {
            // TODO Auto-generated constructor stub
             init();
        }
    
        /**
         * 
         * @Title: registerListener 
         * @Description: TODO(将需要监听方向变化的类注册到OrientationService里,service中的sensor自动打开) 
         * @param listener
         * @throws 
         * @date  2014年7月14日  上午2:29:26 
         * Xuyong
         */
        public void registerListener(OrientationListener listener){
            listenerList.add(listener);
            if(1 == listenerList.size()){
                // 刚刚有新的listener加入的时候打开方向感应器并启动更新线程
                startService();
                mHandler.postDelayed(mCompassViewUpdater, delayMillis);  // delayMillis毫秒执行一次方向更新
            }
        }
        
        /**
         * @Title: unregisterListener 
         * @Description: TODO(再activity pause或者销毁时,讲listener从service移除,service会根据情况自动停止方向感应器的工作) 
         * @param listener
         * @throws 
         * @date  2014年7月14日  上午2:30:45 
         * Xuyong
         */
        public void unregisterListener(OrientationListener listener){
            if((listenerList.remove(listener)) && 0 == listenerList.size()){
                // 如果成功移除listener后导致没有任何listener监听方向变化,暂停方向感应器
                stopService();
            }
        }
        
        /**
         * @Title: setDelayMillis 
         * @Description: TODO(设置更新时间间隔,不得低于10ms) 
         * @param delayMillis
         * @throws 
         * @date  2014年7月14日  上午2:34:10 
         * Xuyong
         */
        public void setDelayMillis(long delayMillis){
            if(delayMillis>10){
                this.delayMillis = delayMillis;
            }
        }
        
        /**
         * @Title: onDestory 
         * @Description: TODO(移除所有的监听类,并停止方向感应器) 
         * @throws 
         * @date  2014年7月14日  上午2:34:46 
         * Xuyong
         */
        public void onDestory(){
            listenerList.clear();
            stopService();
        }
        
        /**
         * @Title: init 
         * @Description: TODO(初始化方向感应器) 
         * @throws 
         * @date  2014年7月14日  上午12:36:53 
         * Xuyong
         */
        @SuppressWarnings("deprecation")
        private void init(){
            sensorManager = (SensorManager) ApplicationContext.getInstance().getContext().getSystemService(android.content.Context.SENSOR_SERVICE);
            try {
                mOrientationSensor = sensorManager.getSensorList(
                        Sensor.TYPE_ORIENTATION).get(0);
            } catch (Exception e) {
                // TODO: handle exception
                mOrientationSensor = null;
            }        
        }
        
        private void stopService(){
            if (mOrientationSensor != null && sensorManager != null) {
                sensorManager.unregisterListener(this);
            }
        }
        
        private void startService(){
            if (mOrientationSensor != null && sensorManager != null) {
                sensorManager.registerListener(this, mOrientationSensor, SensorManager.SENSOR_DELAY_GAME);
            }
        }
        
        /**
         * 这个是更新指南针旋转的线程,handler的灵活使用,每delayMillis毫秒检测方向变化值(这样的机制不太好,可能会出现线程阻滞)
         */
        protected Runnable mCompassViewUpdater = new Runnable() {
            @Override
            public void run() {        
                if (listenerList.size() > 0) {// 有监听的时候,传递下去,并且注意传入顺序为倒序,保证最近的层最先响应。
                    long startTime = SystemClock.uptimeMillis();
                    for(int i = listenerList.size()-1; i>=0; i--){
                        ((OrientationListener) listenerList.get(i)).onOrientationChanged(mTargetDirection);
                    }
                    // 由于线程阻滞,可能带来延时,通过时间控制来弥补
                    long endTime = SystemClock.uptimeMillis();
                    long delayTime = endTime - startTime;
                    delayTime = (delayTime > delayMillis)? 2:(delayMillis-delayTime);
                    mHandler.postDelayed(mCompassViewUpdater, delayTime);    // 比定时器好
                }            
            }
        };
    
        /*
         * no use currently
         */
        @Override
        public void onAccuracyChanged(Sensor arg0, int arg1) {
            // TODO Auto-generated method stub
        }
        
        /**
         * @Title: onSensorChanged 
         * @Description: TODO(直接调用SDK自带的API获取方向信息,以后需要修改为根据加速度和地磁数据的方向计算) 
         * @param event
         * @throws 
         * @date  2014年7月11日  下午4:52:36 
         * Xuyong
         */
        @SuppressWarnings("deprecation")
        @Override
        public void onSensorChanged(SensorEvent event) {
            // TODO Auto-generated method stub
            switch (event.sensor.getType()) {    
            // Note:改方法已经不鼓励使用,考虑在此处修改数据获取方向重新计算方向值
            case Sensor.TYPE_ORIENTATION:
                float direction = event.values[SensorManager.DATA_X] * -1.0f;
                mTargetDirection = (direction + 720) % 360; // 赋值给全局变量,让指南针旋转
                break;
            default:
                break;
            }
        }
    }

    调用方法:

     对任意activity,继承实现OrientationListener,在onResume和onPause中分别注册和注下销listener,代码如下:

     1 public class xxxxActivity  implements  OrientationListener {
     2 
     3     @Override
     4     protected void onPause() {
     5        super.onPause();
     6     ApplicationContext.getInstance().getOrientationService().unregisterListener(this);
     7     }
     8     
     9     @Override
    10     public void onResume() {
    11       super.onResume();
    12       ApplicationContext.getInstance().getOrientationService().registerListener(this);
    13     }
    14 
    15     @Override
    16     public void onOrientationChanged(float orientatoin) {
    17         // TODO Auto-generated method stub
    18         adapter.setOrientation(orientatoin);
    19     } 
    20 }
  • 相关阅读:
    泛型应用----泛型接口、泛型方法、泛型数组、泛型嵌套
    有选择性的启用SAP UI5调试版本的源代码
    SAP UI5应用入口App.controller.js是如何被UI5框架加载的?
    SAP WebIDE里UI5应用的隐藏文件project.json
    SAP UI5的support Assistant
    如何用SAP WebIDE的Fiori创建向导基于ABAP OData service快速创建UI5应用
    SAP Cloud Platform上Destination属性为odata_gen的具体用途
    Marketing Cloud contact主数据的csv导入
    Marketing Cloud的contact merge机制
    如何让某些用户对Marketing Cloud的contact数据只能实施只读操作
  • 原文地址:https://www.cnblogs.com/yxy8023ustc/p/3841999.html
Copyright © 2011-2022 走看看