Android项目开发:指南针应用的实现

  • 1.基于方向传感器
    • activity_main.xml
    • MainActivity.java
  • 2.基于加速度传感器和地磁传感器

在Android中可以使用内置传感器(方向传感器、加速度传感器和地磁传感器等)实现指南针功能,编写出能够辨别手机方位的app。本文将讲述两种方法编写指南针app的方法,一是使用方向传感器,二是将加速度传感器和地磁传感器结合。

1.基于方向传感器

方向传感器是Android的基本传感器之一,通过三维坐标来确定(X,Y,Z)的三个方向,以进一步实现指南针功能。
ps:Sensor.TYPE_ORIENTATION在目前的Android系统中已经不再推荐使用,但是仍然可以通过其来获取数据。

activity_main.xml

简单一点,在layout中只设计了一个imageview来放置指南针的图片,以通过动画转动图片实现指南针功能。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" android:gravity="center"> <ImageViewandroid:id="@+id/imageview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/compass" />
</LinearLayout>

MainActivity.java

思路比较简单,通过SensorEventListener监听传感器事件,获取方向传感器Z轴采集到的数据,转动指南针图片。

import androidx.appcompat.app.AppCompatActivity;import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;public class MainActivity extends AppCompatActivity implements SensorEventListener {//使用方向传感器编写指南针private ImageView imageView;private float currentDegree;private SensorManager sensorManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imageView=(ImageView) findViewById(R.id.imageview);currentDegree=0f;sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);  //获取传感器服务}@Overrideprotected void onResume() {//为方向传感器注册监听器super.onResume();sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),sensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onPause() {//取消监听器super.onPause();sensorManager.unregisterListener(this);}@Overridepublic void onSensorChanged(SensorEvent event) {//保持设备水平,使用水平传感器if(event.sensor.getType()==Sensor.TYPE_ORIENTATION){//取围绕Z轴转过的角度float degree=event.values[0];RotateAnimation rotateAnimation=new RotateAnimation(currentDegree,-degree, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);  //动画转动角度rotateAnimation.setDuration(200); //设置动画持续时间rotateAnimation.setFillAfter(true); //设置动画结束后的保留状态imageView.setAnimation(rotateAnimation);currentDegree=-degree;}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}
}

2.基于加速度传感器和地磁传感器

布局和上面的方法一致,因此可以直接复制上面的activity_main.xml代码,详细介绍一下java代码部分。
在onCreate方法中分别获取了加速度传感器和地磁传感器实例,并给他们都注册了监听器。然后在onSensorChanged()方法中进行判断,如果当前是加速度传感器,就将values数组赋给accelerometerValues数组,如果当前是地磁传感器,就将values数组赋给magneticValues数组。在赋值的时候一定要调用values的clone()方法,不然accelerometerValues和magneticValues将指向同一块引用。
接下来,分别创建一个长度为9的R数组和一个长度为3的values数组,然后调用getRotationMatrix()方法给R数组赋值,再调用getOrientation()方法为values数组赋值,这是values数组中含有手机在所有方向上旋转的弧度了。(可以将弧度转换为度)
最后,在回调方法中利用RotateAnimation和当前旋转过的角度值values[0],可以将图片旋转。

import androidx.appcompat.app.AppCompatActivity;import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;public class MainActivity extends AppCompatActivity implements SensorEventListener {//通过加速度传感器和地磁传感器编写指南针private SensorManager sensorManager;private ImageView imageView;private float lastRotateDegree;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imageView = (ImageView) findViewById(R.id.imageview);sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);//加速度感应器Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);//地磁感应器Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(this, magneticSensor, SensorManager.SENSOR_DELAY_GAME);sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onDestroy() {super.onDestroy();if (sensorManager != null) {sensorManager.unregisterListener(this);}}float[] accelerometerValues = new float[3];float[] magneticValues = new float[3];@Overridepublic void onSensorChanged(SensorEvent event) {// 判断当前是加速度感应器还是地磁感应器if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {//赋值调用clone方法accelerometerValues = event.values.clone();} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {//赋值调用clone方法magneticValues = event.values.clone();}float[] R = new float[9];float[] values = new float[3];SensorManager.getRotationMatrix(R,null,accelerometerValues,magneticValues);sensorManager.getOrientation(R, values);Log.d("Main","values[0] :"+Math.toDegrees(values[0]));//values[0]的取值范围是-180到180度。//+-180表示正南方向,0度表示正北,-90表示正西,+90表示正东//将计算出的旋转角度取反,用于旋转指南针背景图float rotateDegree = -(float) Math.toDegrees(values[0]);if (Math.abs(rotateDegree - lastRotateDegree) > 1) {RotateAnimation animation = new RotateAnimation(lastRotateDegree,rotateDegree, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);animation.setFillAfter(true);imageView.startAnimation(animation); //动画效果转动传感器lastRotateDegree = rotateDegree;}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}
}

最后,附上项目链接

Android项目开发:指南针(两种方法实现)相关推荐

  1. Mixly第三方库开发的两种方法——U8g2库二次开发

    Mixly第三方库开发的两种方法--U8g2库二次开发 前言 方法一:自定义库 1.创建库文件夹 2.开始编程 2.1.定义图形块的基本信息 2.2.定义图形块的外观样式 2.3.定义图形块与C语言的 ...

  2. Android 更新UI的两种方法——handler和runOnUiThread()

    Android 更新UI的两种方法--handler和runOnUiThread() 在Android开发过程中,常需要更新界面的UI.而更新UI是要主线程来更新的,即UI线程更新.如果在主线线程之外 ...

  3. Android启动服务的两种方法

    Android启动服务的两种方法 第一种方法 第二种方法 Android 5.0开始,只能使用显式Intent启动服务.其中,启动服务有2种方式,第一种是直接指定想要启动的服务:第二种是使用AIDL的 ...

  4. 【mybatis基础】mybatis开发dao两种方法

    mybatis是一个支持普通SQL查询,存储过程和高级映射的优秀的持久层的框架,是apache下的顶级项目.mybatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.mybat ...

  5. android沉浸模式代码,Android沉浸式的两种方法

    隐藏状态栏 一个Android应用程序的界面上其实是有很多系统元素的,观察下图: 而打造沉浸式模式的用户体验,就是要将这些系统元素全部隐藏,只留下主体内容部分. 怎么做呢,郭霖的一个Function搞 ...

  6. (最新react-native-0.59.5) 如何将ReactNative项目集成到现有得Android项目中(两种实现方法之一)

    背景:最近在学习React-Native相关的知识,有个需求,如果已经存在一个成熟的Android 或者 IOS项目,如何实现在后续的开发中用RN来实现部分功能.再此我只是讲解一下Android de ...

  7. Android TV 智能电视/盒子 APP 开发焦点控制 两种方法实例

    感谢分享 http://www.7po.com/thread-564068-1-1.html 第一种方法: 采用Android自带的直接控制焦点上下左右的方法.这种方法的前提是必须知道每个view的i ...

  8. android apk 签名方法,[转载]Android apk签名的两种方法

    为了保证每个应用程序开发商合法ID,防止部分开放商可能通过使用相同的Package Name来混淆替换已经安装的程序,我们需要对我们发布的APK文件进行唯一签名,保证我们每次发布的版本的一致性(如自动 ...

  9. android语言切换快捷键,Android的语言设置两种方法

    第一种:修改配置文件 位置:build/target/product/languages_full.mk| languages_small.mk,这两个文件里头,有PRODUCT_LOCALES := ...

  10. Android的语言设置两种方法

    第一种:修改配置文件                    位置:build/target/product/languages_full.mk| languages_small.mk,这两个文件里头, ...

最新文章

  1. php 上传乱码_如何解决php文件上传中文乱码问题
  2. android 绘图之Canvas,Paint类
  3. Velocity知识点总结
  4. 滴滴算法大赛算法解决过程 - 拟合算法
  5. 设计模式C++实现--Interpreter模式
  6. continue break
  7. UOJ351 新年的叶子
  8. php基础知识和函数
  9. 谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family
  10. sublime wrong
  11. LintCode Coins in a Line II
  12. 网站通用 敏感词列表
  13. eXtremeComponents 使用总结
  14. dnf时装补丁教程_DNF补丁教程:就 是 这 么 简 单
  15. 利用kali Linux进行中间人攻击
  16. 百度翻译使用经验(Python版)
  17. JavaGUI--模拟QQ聊天界面私聊群聊
  18. 清橙A1210. 光棱坦克
  19. Office Word 不显示 Citavi 插件,如何修复?
  20. uniapp组件-uni-fav收藏按钮

热门文章

  1. Excel文件的下载
  2. 烽火十八台丨从3.15曝光的食品安全问题看供应链网络安全防护
  3. 谭浩强C++ 第十章
  4. open judge1.7.14
  5. 三星s8android pie,三星修改Galaxy S8的Android Pie更新时间表,并添加M2
  6. 动态网站作业4-JSP中实现数据库的增删改查的操作
  7. adf输稿器是什么_ADF输稿器 多页复印法宝_多功能一体机_办公打印导购-中关村在线...
  8. LOJ#2833 「JOISC 2018 Day 1」帐篷 dp
  9. python3.6.国家政策文本分析代码
  10. 凡事预则立,不预则废——自考有感