センサーのトピック (2)——方向センサー
このセクションの紹介:
前のセクションでは、センサーの基本概念をいくつか学習し、センサーを使用する手順を学習しました。 このセクションで説明するセンサーは、方向センサーの使用法です。それでは、このセクションを始めましょう~
1. 3 次元座標系の概念:
Android プラットフォームでは、センサー フレームは通常、値を表す標準の 3 次元座標系。このセクションをご覧ください 方向センサーを例に挙げてみましょう。結局のところ、私たちの機器は永久に使用できるわけではありません。 これらはすべて水平に保持されます。Android から返される方向の値は、3 つの方向を含む長さ 3 のフラット配列です。 価値!公式 API ドキュメントにはそのような図があります: sensors_overview
画像が理解できない場合は、テキストの説明を書き留めてください:
- X 軸の方向:左から画面の水平方向に沿って右、携帯電話が正方形でない場合は、短い辺が水平である必要があります 置き場所は長辺を垂直に置く必要があります。
- Y軸方向: 画面の左下隅から始まり、画面の垂直方向に沿って画面の上を指す方向
- Z軸方向: 横置きの場合、その方向を指す空の 3 つの値
2. 方向センサーの 3 つの値 前のセクションで説明したように、センサーのコールバック メソッド: onSensorChanged の SensorEvent イベント、event 値のタイプは Float[] で、要素は最大 3 つありますが、方向センサーにはちょうど 3 つの要素があり、すべて度を表します。 対応する意味は次のとおりです:
values[0]: 方位角、携帯電話が Z 軸の周りを回転する角度。 0 は北を意味し、90 は東を意味します。 180 は真南 (South)、270 は真西 (West) を意味します。 value[0] の値がたまたまこれら 4 つの値であった場合、 そして、携帯電話を水平に置いた場合、現在の携帯電話の正面はこの 4 方向になります。 コンパスを書いてみよう!
values[1]: 傾斜角度、携帯電話が傾く度合い。この値は、携帯電話が x 軸の周りに傾くと変化します。価値 範囲は[-180,180]です。携帯電話がデスクトップ上に置かれ、デスクトップが完全に水平である場合、値1は次のようになります。 もちろん、完全に水平なテーブルはほとんどありません。携帯電話 の上部から携帯電話 を持ち上げ始め、携帯電話が X 軸に沿って 180 度回転します (この時点で画面 田舎はテーブルの上に水平に置かれます)。この回転プロセス中に、values[1] の値は 0 から -180 に変化します。つまり、電話が持ち上げられます。 の場合、値 1 は -180 になるまで徐々に小さくなり、携帯電話 の底部から携帯電話が x 軸に沿って移動するまで を持ち上げ始めます。 180度回転すると、values[1]の値が0から180まで変化します。 value[1]のこの特徴を使用して組み合わせることができます value[2]で平らな定規を実装します!
value[2]: スクロール角度、Y 軸に沿ったスクロール角度、値の範囲は [-90,90]、携帯電話の画面が水平上向きに配置されていると仮定します。 デスクトップ上では、この時デスクトップが平らであればvalues2の値は0になるはずです。携帯電話を左側から徐々に持ち上げると、values[2]の値が 携帯電話に対して垂直に配置されるまで徐々に減少します。このとき、values[2]の値は右から0〜90です。 右または左にスクロールし続けると、values[2]の値が-90から90の間で変化し続けます。
よく理解できなくても大丈夫です。デモを書いて確認してみましょう~3. 簡単なデモは、次の 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) {
}
}
コードは非常に簡単です~、これら3つの値の変化を実際に体験したい場合は、プログラムを自分で実行してください。携帯電話に転送するだけでわかります〜
テキストが真南を示したら、コンパスの簡単なテキストバージョンを書いてみましょう。それは携帯電話を意味します すぐ目の前は南です!
レンダリングの実行:
コード実装: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] を 1 つだけ使用し、残りの 2 つを使用します。 また、特定の場所が平らになっているかどうかを測定する、つまり水平定規を作成するためにも使用できます。時間があれば、書いて楽しむこともできます。 わかりました、ありがとうございます~