W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在上一節(jié)中我們中我們對(duì)傳感器的一些基本概念進(jìn)行了學(xué)習(xí),以及學(xué)習(xí)了使用傳感器的套路, 本節(jié)給大家?guī)淼膫鞲衅魇欠较騻鞲衅鞯挠梅ǎ玫?,開始本節(jié)內(nèi)容~
在Android平臺(tái)中,傳感器框架通常是使用一個(gè)標(biāo)準(zhǔn)的三維坐標(biāo)系來表示一個(gè)值的。以本節(jié) 要講的方向傳感器為例子,確定一個(gè)方向也需要一個(gè)三維坐標(biāo),畢竟我們的設(shè)備不可能永遠(yuǎn) 都是水平端著的吧,安卓給我們返回的方向值就是一個(gè)長度為3的flaot數(shù)組,包含三個(gè)方向 的值!官方API文檔中有這樣一個(gè)圖:sensors_overview
如果你看不懂圖,那么寫下文字解釋:
Z軸的方向:當(dāng)水平放置時(shí),指向天空的方向
上一節(jié)中說了,傳感器的回調(diào)方法:onSensorChanged中的參數(shù)SensorEvent event,event的 值類型是Float[]的,而且最多只有三個(gè)元素,而方向傳感器則剛好有三個(gè)元素,都表示度數(shù)! 對(duì)應(yīng)的含義如下:
values[0]:方位角,手機(jī)繞著Z軸旋轉(zhuǎn)的角度。0表示正北(North),90表示正東(East), 180表示正南(South),270表示正西(West)。假如values[0]的值剛好是這四個(gè)值的話, 并且手機(jī)沿水平放置的話,那么當(dāng)前手機(jī)的正前方就是這四個(gè)方向,可以利用這一點(diǎn)來 寫一個(gè)指南針!
values[1]:傾斜角,手機(jī)翹起來的程度,當(dāng)手機(jī)繞著x軸傾斜時(shí)該值會(huì)發(fā)生變化。取值 范圍是[-180,180]之間。假如把手機(jī)放在桌面上,而桌面是完全水平的話,values1的則應(yīng)該 是0,當(dāng)然很少桌子是絕對(duì)水平的。從手機(jī)頂部開始抬起,直到手機(jī)沿著x軸旋轉(zhuǎn)180(此時(shí)屏幕 鄉(xiāng)下水平放在桌面上)。在這個(gè)旋轉(zhuǎn)過程中,values[1]的值會(huì)從0到-180之間變化,即手機(jī)抬起 時(shí),values1的值會(huì)逐漸變小,知道等于-180;而加入從手機(jī)底部開始抬起,直到手機(jī)沿著x軸 旋轉(zhuǎn)180度,此時(shí)values[1]的值會(huì)從0到180之間變化。我們可以利用value[1]的這個(gè)特性結(jié)合 value[2]來實(shí)現(xiàn)一個(gè)平地尺!
value[2]:滾動(dòng)角,沿著Y軸的滾動(dòng)角度,取值范圍為:[-90,90],假設(shè)將手機(jī)屏幕朝上水平放在 桌面上,這時(shí)如果桌面是平的,values2的值應(yīng)為0。將手機(jī)從左側(cè)逐漸抬起,values[2]的值將 逐漸減小,知道垂直于手機(jī)放置,此時(shí)values[2]的值為-90,從右側(cè)則是0-90;加入在垂直位置 時(shí)繼續(xù)向右或者向左滾動(dòng),values[2]的值將會(huì)繼續(xù)在-90到90之間變化!
假如你不是很懂,沒事我們寫個(gè)demo驗(yàn)證下就知道了~
運(yùn)行效果圖:
實(shí)現(xiàn)代碼:
布局代碼:activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="@+id/tv_value1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="方位角"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_value2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="傾斜角"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_value3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="滾動(dòng)角"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private TextView tv_value1;
private TextView tv_value2;
private TextView tv_value3;
private SensorManager sManager;
private Sensor mSensorOrientation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensorOrientation = sManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
sManager.registerListener(this, mSensorOrientation, SensorManager.SENSOR_DELAY_UI);
bindViews();
}
private void bindViews() {
tv_value1 = (TextView) findViewById(R.id.tv_value1);
tv_value2 = (TextView) findViewById(R.id.tv_value2);
tv_value3 = (TextView) findViewById(R.id.tv_value3);
}
@Override
public void onSensorChanged(SensorEvent event) {
tv_value1.setText("方位角:" + (float) (Math.round(event.values[0] * 100)) / 100);
tv_value2.setText("傾斜角:" + (float) (Math.round(event.values[1] * 100)) / 100);
tv_value3.setText("滾動(dòng)角:" + (float) (Math.round(event.values[2] * 100)) / 100);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
代碼非常簡單~,你想真正體驗(yàn)下這三個(gè)值的變化,自己運(yùn)行下程序轉(zhuǎn)轉(zhuǎn)手機(jī)就知道了~
下面我們來寫個(gè)簡單的文字版的指南針來體驗(yàn)體驗(yàn),當(dāng)文字顯示正南的時(shí)候,表示手機(jī) 的正前方就是南方!
運(yùn)行效果圖:
代碼實(shí)現(xiàn):
自定義View:CompassView.java
/**
* Created by Jay on 2015/11/14 0014.
*/
public class CompassView extends View implements Runnable{
private Paint mTextPaint;
private int sWidth,sHeight;
private float dec = 0.0f;
private String msg = "正北 0°";
public CompassView(Context context) {
this(context, null);
}
public CompassView(Context context, AttributeSet attrs) {
super(context, attrs);
sWidth = ScreenUtil.getScreenW(context);
sHeight = ScreenUtil.getScreenH(context);
init();
new Thread(this).start();
}
public CompassView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void init() {
mTextPaint = new Paint();
mTextPaint.setColor(Color.GRAY);
mTextPaint.setTextSize(64);
mTextPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText(msg, sWidth / 4 , sWidth / 2, mTextPaint);
}
// 更新指南針角度
public void setDegree(float degree)
{
// 設(shè)置靈敏度
if(Math.abs(dec - degree) >= 2 )
{
dec = degree;
int range = 22;
String degreeStr = String.valueOf(dec);
// 指向正北
if(dec > 360 - range && dec < 360 + range)
{
msg = "正北 " + degreeStr + "°";
}
// 指向正東
if(dec > 90 - range && dec < 90 + range)
{
msg = "正東 " + degreeStr + "°";
}
// 指向正南
if(dec > 180 - range && dec < 180 + range)
{
msg = "正南 " + degreeStr + "°";
}
// 指向正西
if(dec > 270 - range && dec < 270 + range)
{
msg = "正西 " + degreeStr + "°";
}
// 指向東北
if(dec > 45 - range && dec < 45 + range)
{
msg = "東北 " + degreeStr + "°";
}
// 指向東南
if(dec > 135 - range && dec < 135 + range)
{
msg = "東南 " + degreeStr + "°";
}
// 指向西南
if(dec > 225 - range && dec < 225 + range)
{
msg = "西南 " + degreeStr + "°";
}
// 指向西北
if(dec > 315 - range && dec < 315 + range)
{
msg = "西北 " + degreeStr + "°";
}
}
}
@Override
public void run() {
while(!Thread.currentThread().isInterrupted())
{
try
{
Thread.sleep(100);
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
}
postInvalidate();
}
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private CompassView cView;
private SensorManager sManager;
private Sensor mSensorOrientation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cView = new CompassView(MainActivity.this);
sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensorOrientation = sManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
sManager.registerListener(this, mSensorOrientation, SensorManager.SENSOR_DELAY_UI);
setContentView(cView);
}
@Override
public void onSensorChanged(SensorEvent event) {
cView.setDegree(event.values[0]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
protected void onDestroy() {
super.onDestroy();
sManager.unregisterListener(this);
}
}
這就是一個(gè)很簡單的指南針的雛形了,有興趣的可以自己繪制個(gè)羅盤和指針,然后實(shí)現(xiàn)一個(gè) 好看的指南針~
好的,本節(jié)給大家介紹了Android中最常用的方向傳感器,以及他的簡單用法,以及 寫了一個(gè)指南針的例子,而完成指南針我們只用到一個(gè)values[0]的值,利用其他兩個(gè) 值我們還可以用來測量某地是否平躺,即制作水平尺,有空的可以寫個(gè)來玩玩~ 好的,就到這里,謝謝~
![]()
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: