Android基于多种手机传感器开发指南针的项目
1、基于方向传感器
2、基于加速度传感器和磁场传感器
基于方向传感器的指南针
Java代码——TypeOneActivity.java文件
package com.example.compass00;
import android.app.Activity;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import java.util.List;
public class TypeOneActivity extends Activity implements View.OnClickListener, SensorEventListener {
//使用方向传感器编写指南针
public SensorManager sensorManager;
private float currentDegree;
private TextView tvDirection; //指南针文字显示方位控件
private float azimuth = 0f;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
currentDegree = 0f;
sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
setContentView(R.layout.compass00);
TextView return00 = findViewById(R.id.retuen);
return00.setOnClickListener(this);
TextView exit = findViewById(R.id.exit);
exit.setOnClickListener(this);
tvDirection = (TextView) findViewById(R.id.value01);
}
@Override
public void onResume() {
//为方向传感器注册监听器
super.onResume();
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
for (Sensor s : sensors) {
sensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_FASTEST);
}
}
@Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.retuen:
intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
break;
case R.id.exit:
intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
break;
}
}
@Override
public void onSensorChanged(SensorEvent event) {
TextView value = findViewById(R.id.value);
ImageView imageView = findViewById(R.id.compass);
float[] values = event.values;
StringBuilder stringBuilder = new StringBuilder();
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
stringBuilder.append("方向传感器的返回值:");
stringBuilder.append("\nvalues[0]:" + values[0]);
stringBuilder.append("\nvalues[1]:" + values[1]);
stringBuilder.append("\nvalues[2]:" + values[2]);
value.setText(stringBuilder.toString());
float degree = event.values[0]; //取围绕z轴转过的角度
azimuth = (degree + 360) % 360;
RotateAnimation rotateAnimation = new RotateAnimation(currentDegree, -degree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
if (azimuth <= 15 || azimuth >= 345) {
tvDirection.setText("方位:北");
} else if (15 < azimuth && azimuth < 75) {
tvDirection.setText("方位:东北");
} else if (75 <= azimuth && azimuth <= 105) {
tvDirection.setText("方位:东");
} else if (105 < azimuth && azimuth < 165) {
tvDirection.setText("方位:东南");
} else if (165 <= azimuth && azimuth <= 195) {
tvDirection.setText("方位:南");
} else if (195 < azimuth && azimuth < 255) {
tvDirection.setText("方位:西南");
} else if (255 <= azimuth && azimuth <= 285) {
tvDirection.setText("方位:西");
} else if (285 < azimuth && azimuth < 345) {
tvDirection.setText("方位:西北");
}
rotateAnimation.setDuration(200);
rotateAnimation.setFillAfter(true);
imageView.setAnimation(rotateAnimation);
currentDegree = -degree;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
布局文件——compass00.xml文件
<?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:background="@color/white">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#A3FBC7">
<RelativeLayout
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/retuen"
android:background="@drawable/background01">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_margin="30dp"
android:gravity="center"
android:text="基于方向传感器"
android:textColor="#009688"
android:textSize="26dp" />
<ImageView
android:id="@+id/compass"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_below="@+id/title"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:src="@drawable/compass" />
<TextView
android:id="@+id/value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/compass"
android:layout_alignLeft="@+id/compass"
android:layout_alignRight="@+id/compass"
android:layout_marginTop="30dp"
android:text="方向传感器的返回值:"
android:textColor="#FFC107"
android:textSize="18dp" />
<TextView
android:id="@+id/value01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/value"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:background="@color/teal_200"
android:gravity="center"
android:text="方位"
android:textColor="@color/black"
android:textSize="38dp" />
</RelativeLayout>
<TextView
android:id="@+id/retuen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="@color/teal_700"
android:text="返回上一级"
android:textColor="@color/black"
android:textSize="26dp" />
<TextView
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_margin="8dp"
android:background="#F44336"
android:text="退出软件"
android:textColor="@color/black"
android:textSize="26dp" />
</RelativeLayout>
</LinearLayout>
基于加速度传感器和磁场传感器
Java代码——TypeTwoActivity.Java文件
package com.example.compass00;
import android.app.Activity;
import android.content.Intent;
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.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
public class TypeTwoActivity extends Activity implements View.OnClickListener, SensorEventListener {
//通过加速度传感器和地磁传感器编写指南针
public SensorManager sensorManager;
private Sensor aSensor; //定义加速度传感器
private Sensor mSensor; //定义磁场传感器
private String TAG = "CompassActivity";
public ImageView ivArrow; //指南针指针控件
private TextView tvDirection; //指南针文字显示方位控件
private float[] mGravity = new float[3];
private float[] mGeomagnetic = new float[3];
private float azimuth = 0f;
private float currentAzimuth = 0;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.compass01);
TextView return00 = findViewById(R.id.retuen);
return00.setOnClickListener(this);
TextView exit = findViewById(R.id.exit);
exit.setOnClickListener(this);
initView();
initData();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (sensorManager != null) {
sensorManager.unregisterListener(this);
}
}
@Override
protected void onResume() {
super.onResume();
if (null != sensorManager) {
// 注册陀螺仪传感器
sensorManager.registerListener(this, aSensor,
SensorManager.SENSOR_DELAY_GAME);
// 注册磁场传感器
sensorManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_GAME);
}
}
@Override
protected void onPause() {
super.onPause();
if (null != sensorManager) {
sensorManager.unregisterListener(this); // 取消注册陀螺仪传感器
}
}
@Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.retuen:
intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
break;
case R.id.exit:
intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
break;
}
}
@Override
public void onSensorChanged(SensorEvent event) {
final float alpha = 0.97f;
synchronized (this) {
//指南针转动角度算法
//判断当前是加速度感应器还是地磁感应器
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
TextView value00 = findViewById(R.id.value00);
float[] values = event.values;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("加速度计的返回值:");
stringBuilder.append("\nvalues[0]:" + values[0]);
stringBuilder.append("\nvalues[1]:" + values[1]);
stringBuilder.append("\nvalues[2]:" + values[2]);
value00.setText(stringBuilder.toString());
mGravity[0] = alpha * mGravity[0] + (1 - alpha)
* event.values[0];
mGravity[1] = alpha * mGravity[1] + (1 - alpha)
* event.values[1];
mGravity[2] = alpha * mGravity[2] + (1 - alpha)
* event.values[2];
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
TextView value01 = findViewById(R.id.value01);
float[] values = event.values;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("磁场传感器的返回值:");
stringBuilder.append("\nvalues[0]:" + values[0]);
stringBuilder.append("\nvalues[1]:" + values[1]);
stringBuilder.append("\nvalues[2]:" + values[2]);
value01.setText(stringBuilder.toString());
mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha)
* event.values[0];
mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha)
* event.values[1];
mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha)
* event.values[2];
}
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimuth = (float) Math.toDegrees(orientation[0]); // orientation
azimuth = (azimuth + 360) % 360;
adjustArrow();
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/**
* 初始化控件
*/
private void initView() {
ivArrow = (ImageView) findViewById(R.id.compass);
tvDirection = (TextView) findViewById(R.id.value02);
}
/**
* 初始化数据
*/
private void initData() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
aSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
/**
* 陀螺仪方位显示&角度转动
*/
private void adjustArrow() {
if (ivArrow == null) {
return;
}
Animation an = new RotateAnimation(-currentAzimuth, -azimuth,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
currentAzimuth = azimuth;
Log.i(TAG, "azimuth:" + azimuth);
if (azimuth <= 15 || azimuth >= 345) {
tvDirection.setText("方位:北");
} else if (15 < azimuth && azimuth < 75) {
tvDirection.setText("方位:东北");
} else if (75 <= azimuth && azimuth <= 105) {
tvDirection.setText("方位:东");
} else if (105 < azimuth && azimuth < 165) {
tvDirection.setText("方位:东南");
} else if (165 <= azimuth && azimuth <= 195) {
tvDirection.setText("方位:南");
} else if (195 < azimuth && azimuth < 255) {
tvDirection.setText("方位:西南");
} else if (255 <= azimuth && azimuth <= 285) {
tvDirection.setText("方位:西");
} else if (285 < azimuth && azimuth < 345) {
tvDirection.setText("方位:西北");
}
an.setDuration(200);
an.setRepeatCount(0);
an.setFillAfter(true);
ivArrow.startAnimation(an);//动画效果转动传感器
}
}
布局文件——compass01.xml
<?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:background="@color/white">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#A3FBC7">
<RelativeLayout
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/retuen"
android:background="@drawable/background01">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="20dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:gravity="center"
android:text="基于加速度计和磁场传感器"
android:textColor="#009688"
android:textSize="26dp" />
<ImageView
android:id="@+id/compass"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_below="@+id/title"
android:layout_centerInParent="true"
android:layout_marginTop="30dp"
android:src="@drawable/compass" />
<TextView
android:id="@+id/value00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/compass"
android:layout_alignLeft="@+id/compass"
android:layout_alignRight="@+id/compass"
android:layout_marginTop="10dp"
android:text="加速度计的返回值:"
android:textColor="#FFC107"
android:textSize="18dp" />
<TextView
android:id="@+id/value01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/value00"
android:layout_alignLeft="@+id/compass"
android:layout_alignRight="@+id/compass"
android:layout_marginTop="10dp"
android:text="磁场传感器的返回值:"
android:textColor="#FFC107"
android:textSize="18dp" />
<TextView
android:id="@+id/value02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/value01"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:background="@color/teal_200"
android:gravity="center"
android:text="方位"
android:textColor="@color/black"
android:textSize="38dp" />
</RelativeLayout>
<TextView
android:id="@+id/retuen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="@color/teal_700"
android:text="返回上一级"
android:textColor="@color/black"
android:textSize="26dp" />
<TextView
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="#F44336"
android:text="退出软件"
android:textColor="@color/black"
android:textSize="26dp" />
</RelativeLayout>
</LinearLayout>
app效果图
全部的资源文件以及整个项目代码我已经放在了CSDN中,需要的可以自取https://download.csdn.net/download/weixin_45655279/85545175