实例介绍
【实例简介】Android指南针app,可显示方向/海拔/大气压
【实例截图】
【核心代码】
package perseverance.li.compass; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.location.Criteria; import android.os.Bundle; import android.os.Handler; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.animation.AccelerateInterpolator; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import java.util.Locale; import perseverance.li.compass.view.CompassView; public class CompassActivity extends Activity { private final float MAX_ROATE_DEGREE = 1.0f; private SensorManager mSensorManager; private Sensor mOrientationSensor; private Sensor mPressureSensor; private float mDirection; private float mTargetDirection; private AccelerateInterpolator mInterpolator; protected final Handler mHandler = new Handler(); private boolean mStopDrawing; private boolean mChinease; View mCompassView; CompassView mPointer; TextView mAltitudeTextView; TextView mPressureTextView; LinearLayout mDirectionLayout; LinearLayout mAngleLayout; protected Runnable mCompassViewUpdater = new Runnable() { @Override public void run() { if (mPointer != null && !mStopDrawing) { if (mDirection != mTargetDirection) { // calculate the short routine float to = mTargetDirection; if (to - mDirection > 180) { to -= 360; } else if (to - mDirection < -180) { to = 360; } // limit the max speed to MAX_ROTATE_DEGREE float distance = to - mDirection; if (Math.abs(distance) > MAX_ROATE_DEGREE) { distance = distance > 0 ? MAX_ROATE_DEGREE : (-1.0f * MAX_ROATE_DEGREE); } // need to slow down if the distance is short mDirection = normalizeDegree(mDirection ((to - mDirection) * mInterpolator.getInterpolation(Math .abs(distance) > MAX_ROATE_DEGREE ? 0.4f : 0.3f))); mPointer.updateDirection(mDirection); } updateDirection(); mHandler.postDelayed(mCompassViewUpdater, 20); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.compass_layout); initResources(); initServices(); } @Override protected void onResume() { super.onResume(); if (mOrientationSensor != null) { mSensorManager.registerListener(mOrientationSensorEventListener, mOrientationSensor, SensorManager.SENSOR_DELAY_GAME); } if (mPressureSensor != null) { mSensorManager.registerListener(mPressureSensorEventListener, mPressureSensor, SensorManager.SENSOR_DELAY_GAME); } mStopDrawing = false; mHandler.postDelayed(mCompassViewUpdater, 20); } @Override protected void onPause() { super.onPause(); mStopDrawing = true; if (mOrientationSensor != null) { mSensorManager.unregisterListener(mOrientationSensorEventListener); } if (mPressureSensor != null) { mSensorManager.unregisterListener(mPressureSensorEventListener); } } private void initResources() { mDirection = 0.0f; mTargetDirection = 0.0f; mInterpolator = new AccelerateInterpolator(); mStopDrawing = true; mChinease = TextUtils.equals(Locale.getDefault().getLanguage(), "zh"); mCompassView = findViewById(R.id.view_compass); mPointer = (CompassView) findViewById(R.id.compass_pointer); mAltitudeTextView = (TextView) findViewById(R.id.textview_altitude); mPressureTextView = (TextView) findViewById(R.id.textview_pressure); mDirectionLayout = (LinearLayout) findViewById(R.id.layout_direction); mAngleLayout = (LinearLayout) findViewById(R.id.layout_angle); mPointer.setImageResource(mChinease ? R.mipmap.compass_cn : R.mipmap.compass); } private void initServices() { // sensor manager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mOrientationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); mPressureSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); // location manager Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); } private void updateDirection() { LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); mDirectionLayout.removeAllViews(); mAngleLayout.removeAllViews(); ImageView east = null; ImageView west = null; ImageView south = null; ImageView north = null; float direction = normalizeDegree(mTargetDirection * -1.0f); if (direction > 22.5f && direction < 157.5f) { // east east = new ImageView(this); east.setImageResource(mChinease ? R.mipmap.e_cn : R.mipmap.e); east.setLayoutParams(lp); } else if (direction > 202.5f && direction < 337.5f) { // west west = new ImageView(this); west.setImageResource(mChinease ? R.mipmap.w_cn : R.mipmap.w); west.setLayoutParams(lp); } if (direction > 112.5f && direction < 247.5f) { // south south = new ImageView(this); south.setImageResource(mChinease ? R.mipmap.s_cn : R.mipmap.s); south.setLayoutParams(lp); } else if (direction < 67.5 || direction > 292.5f) { // north north = new ImageView(this); north.setImageResource(mChinease ? R.mipmap.n_cn : R.mipmap.n); north.setLayoutParams(lp); } if (mChinease) { // east/west should be before north/south if (east != null) { mDirectionLayout.addView(east); } if (west != null) { mDirectionLayout.addView(west); } if (south != null) { mDirectionLayout.addView(south); } if (north != null) { mDirectionLayout.addView(north); } } else { if (south != null) { mDirectionLayout.addView(south); } if (north != null) { mDirectionLayout.addView(north); } if (east != null) { mDirectionLayout.addView(east); } if (west != null) { mDirectionLayout.addView(west); } } int direction2 = (int) direction; boolean show = false; if (direction2 >= 100) { mAngleLayout.addView(getNumberImage(direction2 / 100)); direction2 %= 100; show = true; } if (direction2 >= 10 || show) { mAngleLayout.addView(getNumberImage(direction2 / 10)); direction2 %= 10; } mAngleLayout.addView(getNumberImage(direction2)); ImageView degreeImageView = new ImageView(this); degreeImageView.setImageResource(R.mipmap.degree); degreeImageView.setLayoutParams(lp); mAngleLayout.addView(degreeImageView); } private ImageView getNumberImage(int number) { ImageView image = new ImageView(this); LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); switch (number) { case 0: image.setImageResource(R.mipmap.number_0); break; case 1: image.setImageResource(R.mipmap.number_1); break; case 2: image.setImageResource(R.mipmap.number_2); break; case 3: image.setImageResource(R.mipmap.number_3); break; case 4: image.setImageResource(R.mipmap.number_4); break; case 5: image.setImageResource(R.mipmap.number_5); break; case 6: image.setImageResource(R.mipmap.number_6); break; case 7: image.setImageResource(R.mipmap.number_7); break; case 8: image.setImageResource(R.mipmap.number_8); break; case 9: image.setImageResource(R.mipmap.number_9); break; } image.setLayoutParams(lp); return image; } private SensorEventListener mOrientationSensorEventListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { float direction = event.values[0] * -1.0f; mTargetDirection = normalizeDegree(direction); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; private SensorEventListener mPressureSensorEventListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { mAltitudeTextView.setText(getString(R.string.altitude, (int) calculateAltitude(event.values[0]))); mPressureTextView.setText(getString(R.string.pressure, event.values[0] / 10)); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; private float calculateAltitude(float pressure) { float sp = 1013.25f; //standard pressure return (sp - pressure) * 100.0f / 12.7f; } private float normalizeDegree(float degree) { return (degree 720) % 360; } }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论