센서 주제 (2) - 방향 센서
이 섹션 소개:
이전 섹션에서 우리는 센서의 몇 가지 기본 개념을 배웠고 센서 사용 루틴을 배웠습니다. 이번 섹션에서 소개할 센서는 방향 센서의 사용법입니다. 이제 시작하겠습니다~
1. 3차원 좌표계의 개념:
Android 플랫폼에서 센서 프레임은 일반적으로 값을 표현하기 위한 표준 3차원 좌표계. 이 섹션을 가져가세요 방향 센서를 예로 들어보겠습니다. 방향을 결정하려면 결국 3차원 좌표가 필요합니다. Android에서 반환한 방향 값은 세 방향을 포함하여 길이가 3인 평면 배열입니다. 값! 공식 API 문서에 다음과 같은 그림이 있습니다: sensors_overview
그림을 이해할 수 없다면 텍스트 설명을 적어주세요:
- X축 방향: 왼쪽에서 화면의 가로 방향으로 오른쪽, 휴대폰이 정사각형이 아닌 경우 짧은 쪽이 가로로 되어야 합니다. 배치할 때는 긴 쪽을 수직으로 배치해야 합니다.
- Y축 방향: 화면 왼쪽 하단에서 시작하여 화면의 세로 방향을 따라 화면 상단을 가리킴
- Z축 방향: 가로로 배치했을 때 방향을 가리킴 of the sky
2. 방향 센서의 세 가지 값
이전 섹션에서 언급한 것처럼 센서 콜백 방법: onSensorChanged의 매개변수 SensorEvent 이벤트, 이벤트 값 유형은 Float[]이고 최대 3개의 요소를 갖는 반면, 방향 센서는 정확히 3개의 요소를 가지며 모두 각도를 나타냅니다! 해당 의미는 다음과 같습니다.
values[0]: 방위각, Z축을 중심으로 휴대폰이 회전하는 각도. 0은 북쪽, 90은 동쪽을 의미합니다. 180은 정남(남쪽), 270은 정서(서쪽)를 의미합니다. 값[0]의 값이 우연히 이 네 가지 값인 경우, 그리고 휴대폰을 수평으로 놓으면 휴대폰의 현재 전면이 이 네 방향이 됩니다. 나침반을 써라!
값[1]: 기울기 각도, 휴대폰이 기울어지는 정도. 이 값은 휴대폰이 x축을 기준으로 기울어지면 변경됩니다. 값 범위는 [-180,180] 사이입니다. 전화기가 바탕 화면에 놓여 있고 바탕 화면이 완전히 수평인 경우 값은 1이어야 합니다. 는 0입니다. 물론 완전히 수평인 테이블은 거의 없습니다. 휴대전화가 x축을 따라 180도 회전할 때까지 휴대전화 상단 에서 들어 올리기 시작합니다(이때 화면은 탁상 위에 수평으로 놓인 시골). 이 회전 과정에서 값[1]의 값이 0에서 -180으로 변경됩니다. 즉, 전화기가 들어 올려집니다. , 값 1은 -180과 같을 때까지 점차 작아지고 전화기가 x축을 따라 이동할 때까지 전화기 아래쪽 을 들어 올리기 시작합니다. 180도 회전하면 값[1]의 값이 0에서 180으로 변경됩니다. 이 가치 특성[1]을 사용하여 결합할 수 있습니다. value[2] 평면자를 구현해보세요!
값[2]: 스크롤 각도, Y축 스크롤 각도, 값 범위: [-90,90], 휴대폰 화면이 수평 위쪽으로 배치되었다고 가정 바탕화면에서 이때 바탕화면이 평평하다면 값2의 값은 0이 되어야 합니다. 휴대폰을 왼쪽부터 서서히 들어올리면 value[2]의 값이 이때 값[2]의 값은 -90이고 오른쪽부터 0~90까지 수직 위치에 추가됩니다. 계속 오른쪽이나 왼쪽으로 스크롤하면 값[2]의 값이 -90에서 90 사이에서 계속 변경됩니다! 잘 이해가 안 되더라도 괜찮습니다. 데모를 작성해 확인해 보세요~
3. 간단한 데모를 통해 다음 세 가지 값의 변화를 이해할 수 있습니다.렌더링 실행
:
구현 코드
: 레이아웃 코드:
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="滚动角"
android:textSize="18sp"
android:textStyle="bold" /></LinearLayout>
: 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("滚动角:" + (float) (Math.round(event.values[2] * 100)) / 100);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
코드는 매우 간단합니다~, 이 세 가지 값의 변화를 실제로 경험하고 싶다면 , 프로그램을 직접 실행해 보세요~
텍스트가 진남을 표시할 때 경험해 볼 수 있는 간단한 텍스트 버전을 작성해 보겠습니다. 휴대폰을 뜻해요 바로앞이 남쪽이에요!
렌더링 실행:
코드 구현:Custom 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)
{
// 设置灵敏度
if(Math.abs(dec - degree) >= 2 )
{
dec = degree;
int range = 22;
String degreeStr = String.valueOf(dec);
// 指向正北
if(dec > 360 - range && dec 90 - range && dec 180 - range && dec 270 - range && dec 45 - range && dec 135 - range && dec 225 - range && 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();
}
}
}
: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);
}
}
이것은 매우 간단한 나침반입니다. 프로토타입, 당신이 그렇다면 관심이 있으시면 나침반과 포인터를 직접 그려서 구현해 보세요.
보기 좋은 나침반~
5. 이 섹션의 샘플 코드 다운로드:
이 섹션 요약:
이 섹션에서는 가장 일반적으로 사용되는 방향 센서를 소개합니다. Android의 간단한 사용법과 나침반의 예를 작성했습니다. 나침반을 완성하려면 값[0] 하나만 사용하고 나머지 두 개를 사용합니다. 특정 장소가 평평하게 누워 있는지 측정하는 데에도 사용할 수 있습니다. 즉, 레벨자를 만드는 데에도 사용할 수 있습니다. 시간이 있으면 재미로 작성해 보세요~ 그렇군요. 감사합니다~