Android 指南针






4.94/5 (21投票s)
本文演示了在 Android 中创建指南针应用程序。
引言
本文解释了我们如何使用移动设备的内置磁传感器创建我们自己的指南针应用程序。
首先要记住的是,指南针应用程序通过使用移动设备上的磁力计传感器提供的数据来工作。 因此,如果我们的移动设备没有这个传感器,指南针应用程序就无法运行。
此外,磁力计对磁信号或电信号非常敏感。 因此,请小心,您要将设备远离任何此类信号,以从指南针应用程序获得准确的方向。
我使用了 cliparts.co 的以下图像作为我的指南针应用程序的指南针图片
背景
在本文中,我使用 TextView 控件来显示设备的方向角。 此外,我使用了一个指南针的图像来指向南北方向。 为了使这一切起作用,需要在初始化应用程序时初始化设备的传感器管理器。
此外,我们需要在激活应用程序时注册设备的方向传感器,并在应用程序暂停时注销它,以节省电池电量。
使用代码
以下是主布局文件,它在相对布局中定义了一个 TextView 控件和一个 ImageView 控件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:orientation="vertical" > <TextView android:id="@+id/txtDegrees" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/imgCompass" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/txtDegrees" android:src="@drawable/compass" /> </RelativeLayout>
以下代码用于初始化指南针的图像。
imgCompass=(ImageView)findViewById(R.id.imgCompass);
以下代码用于初始化文本视图以显示旋转角度。
txtDegrees=(TextView)findViewById(R.id.txtDegrees);
getSystemService()
方法可用于初始化我们设备的传感器管理器,如下所示
sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);
以下是 onCreate()
方法的完整代码,该方法在应用程序启动时只调用一次
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imgCompass=(ImageView)findViewById(R.id.imgCompass); txtDegrees=(TextView)findViewById(R.id.txtDegrees); sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE); }
以下是 onResume() 方法的代码,每当活动进入前台时都会自动调用
@Override protected void onResume() { super.onResume(); sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_GAME); }
上面的代码为设备的方向传感器注册了一个 SensorEventListener,采样频率由参数 SensorManager.SENSOR_DELAY_GAME 指定,该参数表示适用于游戏的速率。
以下代码在活动暂停时注销 SensorEventListener。
@Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); }
主要操作发生在以下 onSensorChanged() 方法中。 只要传感器值发生变化,就会执行 onSensorChanged() 方法。
@Override public void onSensorChanged(SensorEvent event) { float degree=Math.round(event.values[0]); txtDegrees.setText("Rotation: "+Float.toString(degree)+" degrees"); RotateAnimation ra=new RotateAnimation(currentDegree,-degree,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); ra.setDuration(120); ra.setFillAfter(true); imgCompass.startAnimation(ra); currentDegree=-degree; }
在上面的代码中,SensorEvent 是 onSensorChanged() 方法的参数。
旋转角度由代码 float degree=Math.round(event.values[0]);
确定,并使用 setText()
方法显示在 TextView 上。
values
数组的大小和数据取决于传感器类型。
对于方向传感器,values
数组包含以下值
- values[0]: 磁北方向与 y 轴在 z 轴周围的角度(0 到 359),其中 0=北,90=东,180=南,270=西。
- values[1]: 绕 x 轴旋转(-180 到 180),当 z 轴向 y 轴移动时为正值。
- values[2]: 绕 x 轴旋转,(-90 到 90),设备顺时针移动时增加。
之后,使用 RotateAnimation 对象来旋转指南针,随着设备旋转。 RotateAnimation 类的构造函数采用以下参数
- fromDegrees: 动画开始时的旋转偏移量。
- toDegrees: 动画结束时的旋转偏移量。
- pivotXType: pivotXValue 的解释。 可以是 Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF 或 Animation.RELATIVE_TO_PARENT。
- pivotXValue: 对象旋转点的 X 坐标。
- pivotYType: pivotYValue 的解释。 可以是 Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF 或 Animation.RELATIVE_TO_PARENT。
- pivotYValue: 对象旋转点的 Y 坐标。
Animation 类的 setDuration()
方法用于指定动画持续的毫秒数。
Animation 类的 setFillAfter()
方法用于保留此动画产生的变换。
Animation 类的 startAnimation()
方法用于启动动画。
最后,currentDegree 使用 -degree 的值进行更新,以便下一个动画从新的位置开始。
以下函数未使用,但需要指定,因为我们的活动类实现了 SensorEventListener 接口
@Override public void onAccuracyChanged(Sensor p1, int p2) { }
以下是在我的三星 Galaxy Note 3 Neo 手机上执行指南针应用程序的输出
关注点
我希望这篇文章能帮助读者理解创建我们自己的指南针应用程序是多么容易。