简易指南针
来源:互联网 发布:如何学好c语言编程 编辑:程序博客网 时间:2024/04/28 23:39
Android中的方向传感器在生活中是一个很好的应用,典型的例子是指南针的使用,我们先来简单介绍一下传感器中三个参数x,y,z的含义,以一幅图来说明。
图 1
补充说明:图中的坐标轴x,y,z和传感器中的X,Y,Z没有任何联系!
如上图所示,绿色部分表示一个手机,带有小圈那一头是手机头部
传感器中的X:如上图所示,规定X正半轴为北,手机头部指向OF方向,此时X的值为0,如果手机头部指向OG方向,此时X值为90,指向OH方向,X值为180,指向OE,X值为270
传感器中的Y:现在我们将手机沿着BC轴慢慢向上抬起,即手机头部不动,尾部慢慢向上翘起来,直到AD跑到BC右边并落在XOY平面上,Y的值将从0~180之间变动,如果手机沿着AD轴慢慢向上抬起,即手机尾部不懂,直到BC跑到AD左边并且落在XOY平面上,Y的值将从0~-180之间变动,这就是方向传感器中Y的含义。
传感器中的Z:现在我们将手机沿着AB轴慢慢向上抬起,即手机左边框不动,右边框慢慢向上翘起来,直到CD跑到AB右边并落在XOY平面上,Z的值将从0~180之间变动,如果手机沿着CD轴慢慢向上抬起,即手机右边框不动,直到AB跑到CD左边并且落在XOY平面上,Z的值将从0~-180之间变动,这就是方向传感器中发Z的含义。
了解了方向传感器中X,Y,Z的含义之后下面我们就开始学习如何使用
首先我们创建一个传感器管理器和一个传感器监听器,管理器用来管理传感器以及创建各种各样的传感器,监听器用来监视传感器的变化并且进行相应的操作
private SensorManager sensorManager;
private MySensorEventListener mySensorEventListener;
mySensorEventListener= new MySensorEventListener();//这个监听器当然是我们自己定义的,在方向感应器感应到手机方向有变化的时候,我们可以采取相应的操作,这里紧紧是将x,y,z的值打印出来
private final class MySensorEventListener implements SensorEventListener{@Override//可以得到传感器实时测量出来的变化值public void onSensorChanged(SensorEvent event) {//方向传感器if(event.sensor.getType()==Sensor.TYPE_ORIENTATION){//x表示手机指向的方位,0表示北,90表示东,180表示南,270表示西float x = event.values[SensorManager.DATA_X];float y = event.values[SensorManager.DATA_Y];float z = event.values[SensorManager.DATA_Z];//tv_orientation是界面上的一个TextView标签,不再赘述tv_orientation.setText("Orientation:"+x+","+y+","+z);}}我们在onResume方法中创建一个方向传感器,并向系统注册监听器protected void onResume() { Sensor sensor_orientation=sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); sensorManager.registerListener(mySensorEventListener,sensor_orientation, SensorManager.SENSOR_DELAY_UI);super.onResume();}最后我们在onPause()中注销所有传感器的监听,释放方向感应器资源!protected void onPause() {//注销所有传感器的监听sensorManager.unregisterListener(mySensorEventListener);super.onPause();}
下面制作一个简单的指南针:
1、写一个MyView类继承SurfaceView
public class MyView extends SurfaceView implements SurfaceHolder.Callback{//继承SurfaceView 插入构造器 private int width; private int height; private Paint mPaintCircle; private Paint mPaintText; private Paint mPaintLine; private String[] sensor = {"W", "N","E","S"}; private Float degree;//角度 private boolean work = true;//对degree插入setter和getter方法 public void setDegree(Float degree) { this.degree = degree; } public Float getDegree() { return degree; }//两个构造器 public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); SurfaceHolder holder = getHolder();//得到holder holder.addCallback(this);//绑定holder的回 mPaintCircle = new Paint(); mPaintCircle.setColor(Color.BLACK); mPaintCircle.setStyle(Paint.Style.STROKE); mPaintCircle.setStrokeWidth(5); mPaintText = new Paint(); mPaintText.setColor(Color.RED); mPaintText.setStrokeWidth(10); mPaintText.setTextSize(20); mPaintLine = new Paint(); mPaintLine.setColor(Color.GREEN); mPaintLine.setStrokeWidth(10); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); }// implements SurfaceHolder.Callback后实现下面的三个方法 @Override public void surfaceCreated(final SurfaceHolder holder) { //启动线程 new Thread(new Runnable() { @Override public void run() { while (work) { Canvas canvas = holder.lockCanvas(); //接下来绘制东西,相当于onDrawn()方法 canvas.drawColor(Color.GRAY); canvas.drawCircle(width / 2, height / 2, 200, mPaintCircle); canvas.drawCircle(width / 2, height / 2, 10, mPaintCircle); for (int i = 1; i <= sensor.length; i++) {//用FOR循环画12条短线 canvas.save();//保存画布当前的状态 canvas.rotate(360 / 4 * i+degree, width / 2, height / 2);//旋转画布,每次转90度 canvas.drawText("" + sensor[i - 1], width / 2, height / 2 - 180, mPaintText); canvas.restore(); } canvas.save(); canvas.rotate(degree, width / 2, height / 2);//从activity中得到旋转的角度 canvas.drawLine(width / 2, height / 2, width / 2, height / 2 - 160, mPaintLine); canvas.restore(); holder.unlockCanvasAndPost(canvas); try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { holder.setFixedSize(this.width,this.height); } @Override public void surfaceDestroyed(SurfaceHolder holder) { work = false; }}
2、在布局文件中声明MyView
<com.my.administrator.myseneor.MyView android:id="@+id/view" android:layout_width="match_parent" android:layout_height="match_parent" />
3、 MainActivity
public class MainActivity extends AppCompatActivity { private SensorManager sensorManager; private MyView myView; private float degree; float[] acceleromoterValues = new float[3];//加速度传感器的三个值 float[] magneticValues = new float[3];//地磁传感器的三个值 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (MyView) findViewById(R.id.view); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);//获得sensorManager的实例,sensorManager是所有传感器的管理器,有了它之后就可以调用getDefaultSensor方法得到任意的传感器类型了。 Sensor magegeticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //调用registerListener方法注册才能生效 sensorManager.registerListener(listener, magegeticSensor, SensorManager.SENSOR_DELAY_GAME); sensorManager.registerListener(listener, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME); } @Override protected void onDestroy() { super.onDestroy(); if (sensorManager != null) { sensorManager.unregisterListener(listener); } } private SensorEventListener listener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { //判断当前是加速度传感器还是地磁传感器 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { //注意赋值时要调用clone()方法 acceleromoterValues = event.values.clone(); } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { magneticValues = event.values.clone(); } float[] R = new float[9]; float[] values = new float[3]; SensorManager.getRotationMatrix(R, null, acceleromoterValues, magneticValues); SensorManager.getOrientation(R, values); //第一个values的值就是手机旋转的角度 Log.d("MainActivity", "values[0] is" + Math.toDegrees(values[0])); degree = (float)-Math.toDegrees(values[0]); Log.d("MainActivity", "这里指针转过了" + degree); myView.setDegree(degree);//通过setDegree方法将角度传到myview中去,然后指针相应偏转 } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } };}
- 简易指南针
- 一个简易的指南针
- Android简易指南针
- 简易指南针的实现
- Android 简易指南针
- Android传感器的使用开发、简易指南针
- Android传感器的使用开发、简易指南针
- 指南针
- 指南针
- 指南针
- 指南针
- 指南针
- 指南针
- 指南针
- Android中方向传感器的用法,制作简易指南针
- SensorManager的方向传感器Orientation -- 指南针的简易实现
- Android笔记(十九)制作一个简易的指南针
- Android移动开发-调用方向传感器开发简易指南针的实现
- 面试心得与总结
- UVA 10518 How Many Calls?
- 使用SharedPreferences读写文件到内存
- iOS经典讲解之多线程应用场景
- MySQL的分层数据管理与无限级分类
- 简易指南针
- get请求返回中文乱码问题
- 模板(泛型)
- HDOJ 1076 An Easy Task (第n个闰年)
- input file文件上传CSS模拟为 选择 加 上传 两个按钮
- 利用bootstrap Grid栅格系统的向下缩小特性排版
- MySQL Meta中的length字段 -- (2) length的推导
- ios多线程开发详解
- ImageView、RadioButton、CheckBox等控件学习