600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > android方向传感器 指南针 Android 方向传感器的两个应用:指南针和水平仪

android方向传感器 指南针 Android 方向传感器的两个应用:指南针和水平仪

时间:2019-12-12 21:39:45

相关推荐

android方向传感器 指南针 Android 方向传感器的两个应用:指南针和水平仪

简单指南针的实现:将方向传感器的第一个参数(与正北方的夹角)传递给图片,进行旋转动画反向相等的角度

public class MainActivity extends Activity implements SensorEventListener

{

// 定义显示指南针的图片

ImageView znzImage;

// 记录指南针图片转过的角度

float currentDegree = 0f;

SensorManager mSensorManager;

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// 获取界面中显示指南针的图片

znzImage = (ImageView) findViewById(R.id.znzImage);

mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);

}

@Override

protected void onResume()

{

super.onResume();

// 为系统的方向传感器注册监听器

mSensorManager.registerListener(this,

mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),

SensorManager.SENSOR_DELAY_GAME);

}

@Override

protected void onPause()

{

// 取消注册

mSensorManager.unregisterListener(this);

super.onPause();

}

@Override

protected void onStop()

{

// 取消注册

mSensorManager.unregisterListener(this);

super.onStop();

}

@Override

public void onSensorChanged(SensorEvent event)

{

int sensorType = event.sensor.getType();

if(sensorType==Sensor.TYPE_ORIENTATION){

float degree = event.values[0];

// 创建旋转动画(反向转过degree度)

RotateAnimation ra = new RotateAnimation(currentDegree,

-degree, Animation.RELATIVE_TO_SELF, 0.5f,

Animation.RELATIVE_TO_SELF, 0.5f);

// 设置动画的持续时间

ra.setDuration(200);

// 运行动画

znzImage.startAnimation(ra);

currentDegree = -degree;

}

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy)

{

}

}

水平仪:将方向传感器返回的底部、右侧翘起角度传给气泡图片,控制其在屏幕上的位置

public class MyView extends View

{

// 定义水平仪仪表盘图片

Bitmap back;

// 定义水平仪中的气泡图标

Bitmap bubble;

// 定义水平仪中气泡 的X、Y座标

int bubbleX, bubbleY;

public MyView(Context context, AttributeSet attrs)

{

super(context, attrs);

// 加载水平仪图片和气泡图片

back = BitmapFactory.decodeResource(getResources()

, R.drawable.back);

bubble = BitmapFactory

.decodeResource(getResources(), R.drawable.bubble);

}

@Override

protected void onDraw(Canvas canvas)

{

super.onDraw(canvas);

// 绘制水平仪表盘图片

canvas.drawBitmap(back, 0, 0, null);

// 根据气泡座标绘制气泡

canvas.drawBitmap(bubble, bubbleX, bubbleY, null);

}

}

public class MainActivity extends Activity implements SensorEventListener

{

// 定义水平仪的仪表盘

MyView show;

// 定义水平仪能处理的最大倾斜角,超过该角度,气泡将直接在位于边界。

int MAX_ANGLE = 30;

// // 定义真机的Sensor管理器

SensorManager mSensorManager;

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// 获取水平仪的主组件

show = (MyView) findViewById(R.id.show);

mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);

}

@Override

public void onResume()

{

super.onResume();

// 为系统的方向传感器注册监听器

mSensorManager.registerListener(this,

mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),

SensorManager.SENSOR_DELAY_GAME);

}

@Override

protected void onPause()

{

// 取消注册

mSensorManager.unregisterListener(this);

super.onPause();

}

@Override

protected void onStop()

{

// 取消注册

mSensorManager.unregisterListener(this);

super.onStop();

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy)

{

}

@Override

public void onSensorChanged(SensorEvent event)

{

float[] values = event.values;

// // 真机上获取触发event的传感器类型

int sensorType = event.sensor.getType();

if(sensorType==Sensor.TYPE_ORIENTATION){

// 获取与Y轴的夹角

float yAngle = values[1];

// 获取与Z轴的夹角

float zAngle = values[2];

// 气泡位于中间时(水平仪完全水平),气泡的X、Y座标

int x = (show.back.getWidth() - show.bubble.getWidth()) / 2;

int y = (show.back.getHeight() - show.bubble.getHeight()) / 2;

// 如果与Z轴的倾斜角还在最大角度之内

if (Math.abs(zAngle) <= MAX_ANGLE)

{

// 根据与Z轴的倾斜角度计算X座标的变化值(倾斜角度越大,X座标变化越大)

int deltaX = (int) ((show.back.getWidth() - show.bubble

.getWidth()) / 2 * zAngle / MAX_ANGLE);

x += deltaX;

}

// 如果与Z轴的倾斜角已经大于MAX_ANGLE,气泡应到最左边

else if (zAngle > MAX_ANGLE)

{

x = 0;

}

// 如果与Z轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最右边

else

{

x = show.back.getWidth() - show.bubble.getWidth();

}

// 如果与Y轴的倾斜角还在最大角度之内

if (Math.abs(yAngle) <= MAX_ANGLE)

{

// 根据与Y轴的倾斜角度计算Y座标的变化值(倾斜角度越大,Y座标变化越大)

int deltaY = (int) ((show.back.getHeight() - show.bubble

.getHeight()) / 2 * yAngle / MAX_ANGLE);

y += deltaY;

}

// 如果与Y轴的倾斜角已经大于MAX_ANGLE,气泡应到最下边

else if (yAngle > MAX_ANGLE)

{

y = show.back.getHeight() - show.bubble.getHeight();

}

// 如果与Y轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最右边

else

{

y = 0;

}

// 如果计算出来的X、Y座标还位于水平仪的仪表盘内,更新水平仪的气泡座标

if (isContain(x, y))

{

show.bubbleX = x;

show.bubbleY = y;

}

// 通知系统重回MyView组件

show.postInvalidate();

}

}

// 计算x、y点的气泡是否处于水平仪的仪表盘内

private boolean isContain(int x, int y)

{

// 计算气泡的圆心座标X、Y

int bubbleCx = x + show.bubble.getWidth() / 2;

int bubbleCy = y + show.bubble.getWidth() / 2;

// 计算水平仪仪表盘的圆心座标X、Y

int backCx = show.back.getWidth() / 2;

int backCy = show.back.getWidth() / 2;

// 计算气泡的圆心与水平仪仪表盘的圆心之间的距离。

double distance = Math.sqrt((bubbleCx - backCx) * (bubbleCx - backCx)

+ (bubbleCy - backCy) * (bubbleCy - backCy));

// 若两个圆心的距离小于它们的半径差,即可认为处于该点的气泡依然位于仪表盘内

if (distance < (show.back.getWidth() - show.bubble.getWidth()) / 2)

{

return true;

}

else

{

return false;

}

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。