作业——在线学习Android课程之第十周(传感器与LBS)
2016-05-09 01:21
645 查看
一、什么是传感器:
所谓传感器能够探测如光、热、温度、重力、方向 等等的功能!
二、Android中提供传感器有哪些:
google提供了11种传感器供应用层使用。1、define SENSOR_TYPE_ACCELEROMETER 1 //加速度 2、define SENSOR_TYPE_MAGNETIC_FIELD 2 //磁力 3、define SENSOR_TYPE_ORIENTATION 3 //方向 4、define SENSOR_TYPE_GYROSCOPE 4 //陀螺仪 5、define SENSOR_TYPE_LIGHT 5 //光线感应 6、define SENSOR_TYPE_PRESSURE 6 //压力 7、define SENSOR_TYPE_TEMPERATURE 7 //温度 8、define SENSOR_TYPE_PROXIMITY 8 //接近 9、define SENSOR_TYPE_GRAVITY 9 //重力 10、define SENSOR_TYPE_LINEAR_ACCELERATION 10//线性加速度 11、define SENSOR_TYPE_ROTATION_VECTOR 11//旋转矢量
1 、加速度传感器
加速度传感器又叫G-sensor,返回x、y、z三轴的加速度数值。 该数值包含地心引力的影响,单位是m/s^2。 将手机平放在桌面上,x轴默认为0,y轴默认0,z轴默认9.81。 将手机朝下放在桌面上,z轴为-9.81。 将手机向左倾斜,x轴为正值。 将手机向右倾斜,x轴为负值。 将手机向上倾斜,y轴为负值。 将手机向下倾斜,y轴为正值。 加速度传感器可能是最为成熟的一种mems产品,市场上的加速度传感器种类很多。 手机中常用的加速度传感器有BOSCH(博世)的BMA系列,AMK的897X系列,ST的LIS3X系列等。 这些传感器一般提供±2G至±16G的加速度测量范围,采用I2C或SPI接口和MCU相连,数据精度小于16bit。
2 、磁力传感器
磁力传感器简称为M-sensor,返回x、y、z三轴的环境磁场数据。 该数值的单位是微特斯拉(micro-Tesla),用uT表示。 单位也可以是高斯(Gauss),1Tesla=10000Gauss。 硬件上一般没有独立的磁力传感器,磁力数据由电子罗盘传感器提供(E-compass)。 电子罗盘传感器同时提供下文的方向传感器数据。
3 、方向传感器
方向传感器简称为O-sensor,返回三轴的角度数据,方向数据的单位是角度。 为了得到精确的角度数据,E-compass需要获取G-sensor的数据, 经过计算生产O-sensor数据,否则只能获取水平方向的角度。 方向传感器提供三个数据,分别为azimuth、pitch和roll。 azimuth:方位,返回水平时磁北极和Y轴的夹角,范围为0°至360°。 0°=北,90°=东,180°=南,270°=西。 pitch:x轴和水平面的夹角,范围为-180°至180°。 当z轴向y轴转动时,角度为正值。 roll:y轴和水平面的夹角,由于历史原因,范围为-90°至90°。 当x轴向z轴移动时,角度为正值。 电子罗盘在获取正确的数据前需要进行校准,通常可用8字校准法。 8字校准法要求用户使用需要校准的设备在空中做8字晃动, 原则上尽量多的让设备法线方向指向空间的所有8个象限。 手机中使用的电子罗盘芯片有AKM公司的897X系列,ST公司的LSM系列以及雅马哈公司等等。 由于需要读取G-sensor数据并计算出M-sensor和O-sensor数据, 因此厂商一般会提供一个后台daemon来完成工作,电子罗盘算法一般是公司私有产权。
4、陀螺仪传感器
陀螺仪传感器叫做Gyro-sensor,返回x、y、z三轴的角加速度数据。 角加速度的单位是radians/second。 根据Nexus S手机实测: 水平逆时针旋转,Z轴为正。 水平逆时针旋转,z轴为负。 向左旋转,y轴为负。 向右旋转,y轴为正。 向上旋转,x轴为负。 向下旋转,x轴为正。 ST的L3G系列的陀螺仪传感器比较流行,iphone4和google的nexus s中使用该种传感器。
5 、光线感应传感器
光线感应传感器检测实时的光线强度,光强单位是lux,其物理意义是照射到单位面积上的光通量。 光线感应传感器主要用于Android系统的LCD自动亮度功能。 可以根据采样到的光强数值实时调整LCD的亮度。
6、 压力传感器
压力传感器返回当前的压强,单位是百帕斯卡hectopascal(hPa)。
7 、温度传感器
温度传感器返回当前的温度。
8 、接近传感器
接近传感器检测物体与手机的距离,单位是厘米。 一些接近传感器只能返回远和近两个状态, 因此,接近传感器将最大距离返回远状态,小于最大距离返回近状态。 接近传感器可用于接听电话时自动关闭LCD屏幕以节省电量。 一些芯片集成了接近传感器和光线传感器两者功能。 下面三个传感器是Android2新提出的传感器类型,目前还不太清楚有哪些应用程序使用。
9 、重力传感器
重力传感器简称GV-sensor,输出重力数据。 在地球上,重力数值为9.8,单位是m/s^2。 坐标系统与加速度传感器相同。 当设备复位时,重力传感器的输出与加速度传感器相同。
10、 线性加速度传感器
线性加速度传感器简称LA-sensor。 线性加速度传感器是加速度传感器减去重力影响获取的数据。 单位是m/s^2,坐标系统与加速度传感器相同。 加速度传感器、重力传感器和线性加速度传感器的计算公式如下: 加速度 = 重力 + 线性加速度
11 、旋转矢量传感器
旋转矢量传感器简称RV-sensor。 旋转矢量代表设备的方向,是一个将坐标轴和角度混合计算得到的数据。 RV-sensor输出三个数据: x*sin(theta/2) y*sin(theta/2) z*sin(theta/2) sin(theta/2)是RV的数量级。 RV的方向与轴旋转的方向相同。 RV的三个数值,与cos(theta/2)组成一个四元组。 RV的数据没有单位,使用的坐标系与加速度相同。 举例: 1、sensors_event_t.data[0] = x*sin(theta/2) 2、sensors_event_t.data[1] = y*sin(theta/2) 3、sensors_event_t.data[2] = z*sin(theta/2) 4、sensors_event_t.data[3] = cos(theta/2) GV、LA和RV的数值没有物理传感器可以直接给出, 需要G-sensor、O-sensor和Gyro-sensor经过算法计算后得出。 算法一般是传感器公司的私有产权。
三、加速度传感器应用于重力躲避游戏的实例
public class SurfaceViewAcitvity extends Activity { private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: new AlertDialog.Builder(SurfaceViewAcitvity.this).setTitle("Game Over")//设置对话框标题 .setMessage("重新开始游戏?")//设置显示的内容 .setPositiveButton("确定", new DialogInterface.OnClickListener() {//添加确定按钮 @Override public void onClick(DialogInterface dialog, int which) {//确定按钮的响应事件 // mCoordinates.clear(); // mTime = 0; // mIsRunning = true; // finish(); mAnimView = new MyView(SurfaceViewAcitvity.this); setContentView(mAnimView); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() {//添加返回按钮 @Override public void onClick(DialogInterface dialog, int which) {//响应事件 finish(); } }).show();//在按键响应事件中显示此对话框 break; } } }; MyView mAnimView = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 全屏显示窗口 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //强制竖屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); //LANDSCAPE); // 显示自定义的游戏View mAnimView = new MyView(this); setContentView(mAnimView); } public class MyView extends SurfaceView implements Callback, Runnable, SensorEventListener { /** 每50毫秒刷新一次屏幕 **/ public static final int TIME_IN_FRAME = 50; final int mRadius = 10; int mSpeed = 5; public class Coordinate { private float x; private float y; public Coordinate(int x, int y) { this.x = x; this.y = y; } public float getX() { return x; } public float getY() { return y; } public void setX(float x) { this.x = x; } public void setY(float y) { this.y = y; } } List<Coordinate> mCoordinates = new ArrayList<>(); int mTime = 0; /** 游戏画笔 **/ Paint mPaint = null; SurfaceHolder mSurfaceHolder = null; /** 游戏画布 **/ Canvas mCanvas = null; /** 控制游戏循环 **/ boolean mIsRunning = false; /** SensorManager管理器 **/ private SensorManager mSensorMgr = null; Sensor mSensor = null; /** 手机屏幕宽高 **/ int mScreenWidth = 0; int mScreenHeight = 0; /** 小球资源文件越界区域 **/ private int mScreenBallWidth = 0; private int mScreenBallHeight = 0; /** 小球的坐标位置 **/ private float mPosX = 200; private float mPosY = 0; /** 重力感应X轴 Y轴 Z轴的重力值 **/ private float mGX = 0; private float mGY = 0; private float mGZ = 0; public MyView(Context context) { super(context); /** 设置当前View拥有控制焦点 **/ this.setFocusable(true); /** 设置当前View拥有触摸事件 **/ this.setFocusableInTouchMode(true); /** 拿到SurfaceHolder对象 **/ mSurfaceHolder = this.getHolder(); /** 将mSurfaceHolder添加到Callback回调函数中 **/ mSurfaceHolder.addCallback(this); /** 创建画布 **/ mCanvas = new Canvas(); /** 创建曲线画笔 **/ mPaint = new Paint(); mPaint.setColor(Color.WHITE); /**得到SensorManager对象**/ mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 注册listener,第三个参数是检测的精确度 //SENSOR_DELAY_FASTEST 最灵敏 因为太快了没必要使用 //SENSOR_DELAY_GAME 游戏开发中使用 //SENSOR_DELAY_NORMAL 正常速度 //SENSOR_DELAY_UI 最慢的速度 mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME); } private void Draw() { /**绘制游戏背景**/ mCanvas.drawColor(Color.BLACK); /**绘制小球**/ mPaint.setColor(Color.BLUE); mCanvas.drawCircle(mPosX, mPosY, mRadius, mPaint); mPaint.setColor(Color.RED); Coordinate coordinate; for (int i = 0; i < mCoordinates.size(); i++) { coordinate = mCoordinates.get(i); mCanvas.drawCircle(coordinate.getX(), coordinate.getY(), mRadius, mPaint); } /**X轴 Y轴 Z轴的重力值**/ // mPaint.setColor(Color.WHITE); // mCanvas.drawText("X轴重力值 :" + mGX, 0, 20, mPaint); // mCanvas.drawText("Y轴重力值 :" + mGY, 0, 40, mPaint); // mCanvas.drawText("Z轴重力值 :" + mGZ, 0, 60, mPaint); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { /**开始游戏主循环线程**/ mIsRunning = true; new Thread(this).start(); /**得到当前屏幕宽高**/ mScreenWidth = this.getWidth(); mScreenHeight = this.getHeight(); mPosX = mScreenWidth / 2; mPosY = mScreenHeight / 2; /**得到小球越界区域**/ mScreenBallWidth = mScreenWidth - mRadius * 2; mScreenBallHeight = mScreenHeight - mRadius * 2; } @Override public void surfaceDestroyed(SurfaceHolder holder) { mIsRunning = false; } @Override public void run() { while (mIsRunning) { /** 取得更新游戏之前的时间 **/ long startTime = System.currentTimeMillis(); /** 在这里加上线程安全锁 **/ synchronized (mSurfaceHolder) { /** 拿到当前画布 然后锁定 **/ mCanvas = mSurfaceHolder.lockCanvas(); Coordinate coor; double disx, disy, dis; for (int i = 0; i < mCoordinates.size(); i++) { coor = mCoordinates.get(i); disx = (coor.getX() - mPosX); disy = (coor.getY() - mPosY); dis = Math.sqrt(Math.pow(disx, 2) + Math.pow(disy, 2)); if (dis < mRadius * 2){ mHandler.sendEmptyMessage(0); mIsRunning = false; } else { coor.setX((float)(coor.getX() - mSpeed * disx / dis)); coor.setY((float)(coor.getY() - mSpeed * disy / dis)); } } addredpoint(); Draw(); /** 绘制结束后解锁显示在屏幕上 **/ mSurfaceHolder.unlockCanvasAndPost(mCanvas); } /** 取得更新游戏结束的时间 **/ long endTime = System.currentTimeMillis(); /** 计算出游戏一次更新的毫秒数 **/ int diffTime = (int) (endTime - startTime); /** 确保每次更新时间为50帧 **/ while (diffTime <= TIME_IN_FRAME) { diffTime = (int) (System.currentTimeMillis() - startTime); /** 线程等待 **/ Thread.yield(); } } } private void addredpoint() { if (mTime > 20){ Random random = new Random(); double dis; Coordinate coordinate; do { coordinate = new Coordinate(random.nextInt(mScreenBallWidth) + mRadius, random.nextInt(mScreenBallHeight) + mRadius); dis = Math.pow((coordinate.getX() - mPosX), 2) + Math.pow((coordinate.getY() - mPosY), 2); }while (dis < 400); mCoordinates.add(coordinate); mTime = 0; } else { mTime++; } } @Override public void onAccuracyChanged(Sensor arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onSensorChanged(SensorEvent event) { mGX = event.values[SensorManager.DATA_X]; mGY = event.values[SensorManager.DATA_Y]; mGZ = event.values[SensorManager.DATA_Z]; //这里乘以2是为了让小球移动的更快 mPosX -= mGX * 2; mPosY += mGY * 2; //检测小球是否超出边界 if (mPosX < 0) { mPosX = 0; } else if (mPosX > mScreenBallWidth) { mPosX = mScreenBallWidth; } if (mPosY < 0) { mPosY = 0; } else if (mPosY > mScreenBallHeight) { mPosY = mScreenBallHeight; } } } }
四、LBS的使用
1、到百度地图申请新版本的key,老版本的也可以使用。
http://developer.baidu.com/map/geosdk-android-key.htm
2、在manifes中添加权限,具体参考
< !-- 使用定位所需权限 --> < permission Android:name="android.permission.BAIDU_LOCATION_SERVICE" > < /permission> < uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> < uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> < uses-permission android:name="android.permission.READ_LOGS" /> < uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> 在manifest中添加定位所需要的service <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" > </service> 在application标签中添加你锁申请的key <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="15xihyx7BjNPAuvrAgade2Wo" />
相关文章推荐
- Bitmap API
- Android 混淆Tips
- android tv关于第一次设置默认焦点失效的解决方案
- Android之ViewPager自动循环播放(轮播)效果实现(超简单)
- Android图片资源处理
- Adnroid多媒体---音视频
- 活动的生命周期
- Android Studio集成讯飞语音开发出现21001错误
- Android Bitmap面面观
- Android动态加载技术三个关键问题详解
- 阿里无线的雄心壮志
- 一些快速提高Android开发的脚本与技巧
- Basic4android 的妈妈 Basic4ppc
- Android之Volley框架使用优化--单例模式实现请求队列
- ViewpagerAdapter重要的四个方法解析
- Android studio 开发在真机测试
- repo下载国内链接android源码
- Android之开源框架Universal-Image-Loader简单示例
- 文件读取权限
- Android 工厂模式,三种工厂模式的理解