使用内置 android 传感器的移动方向
Posted
技术标签:
【中文标题】使用内置 android 传感器的移动方向【英文标题】:mobile orientation using in-built android sensors 【发布时间】:2022-01-17 18:41:24 【问题描述】:我是这个领域的新手。我的目标是制作一个 android 应用程序,当在车辆中时,它用于使用 android 内置传感器测量车辆的速度。我面临的问题是我可以使用 TYPE_LINEAR_ACCELERATION 获得加速。但它显示在 3 轴的 3 个不同值上。我能理解的是对于这个应用程序,我应该看看手机是否处于水平位置,那么我应该考虑 Y 轴,如果手机处于水平位置,那么我应该考虑 X 轴。但是我怎么知道手机是水平的还是垂直的?有人可以帮我吗?
它显示错误,我只是复制了您给定的代码: public void onSensorChanged(SensorEvent sensorEvent)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
display?.rotation
else
windowManager.defaultDisplay.orientation
float x=sensorEvent.values[0];
float y=sensorEvent.values[1];
float z=sensorEvent.values[2];
accelerationCurrentValue=Math.abs((Math.sqrt((x*x)+(y*y)+(z*z))-9.8));
accelerationCurrentValue=(double)Math.round(accelerationCurrentValue*1000)/1000;
//update text views
tv_accel.setText(String.valueOf(accelerationCurrentValue));
它显示错误 无法解析符号“显示”、“旋转”、“窗口管理器” 你能告诉我如何解决它们吗?
【问题讨论】:
【参考方案1】:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
display?.rotation
else
windowManager.defaultDisplay.orientation
您可以使用它来获取方向
【讨论】:
嗨,我已将您的代码和我的问题添加到问题中。请帮忙。 请在您的活动中添加此代码。您还可以重写 onConfigurationChange 方法以在方向更改发生时获取方向 你好,我有一个代码,我想显示我将发布我的代码的速度。它没有向我显示速度。【参考方案2】: package com.example.gpslatlongi;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity
public static final int DEFAULT_UPDATE_INTERVAL = 30;
public static final int FAST_UPDATE_INTERVAL = 2;
private static final int PERMISSIONS_FINE_LOCATION = 99;
//reference to the UI elements
TextView tv_lat, tv_lon, tv_altitude, tv_accuracy, tv_speed, tv_sensor, tv_updates, tv_address, tv_accel;
Switch sw_locationupdates, sw_gps;
Handler handler = new Handler();
//define the sensor variables
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private Sensor mGravity;
//variable to remember if we are tracking location or not
boolean updateOn = false;
float appliedAcceleration = 0;
float currentAcceleration = 0;
float velocity = 0;
Date lastUpdate;
//Location request is a config file for all settings related to FusedLocationProviderClient
LocationRequest locationRequest;
LocationCallback locationCallBack;
//Google's API for location services. The majority of the app functions using this class.
FusedLocationProviderClient fusedLocationProviderClient;
private double accelerationCurrentValue;
private SensorEventListener sensorEventListener=new SensorEventListener()
double calibration = Double.NaN;
@Override
public void onSensorChanged(SensorEvent sensorEvent)
double x=sensorEvent.values[0];
double y=sensorEvent.values[1];
double z=sensorEvent.values[2];
accelerationCurrentValue=Math.abs((Math.sqrt((x*x)+(y*y)+(z*z))-9.8));
tv_accel.setText(String.valueOf(accelerationCurrentValue));
if (calibration == Double.NaN)
calibration = accelerationCurrentValue;
else
updateVelocity();
currentAcceleration = (float)accelerationCurrentValue;
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
;
private void updateVelocity()
// Calculate how long this acceleration has been applied.
Date timeNow = new Date(System.currentTimeMillis());
long timeDelta = timeNow.getTime()-lastUpdate.getTime();
lastUpdate.setTime(timeNow.getTime());
// Calculate the change in velocity at the
// current acceleration since the last update.
float deltaVelocity = appliedAcceleration * (timeDelta/1000);
appliedAcceleration = currentAcceleration;
// Add the velocity change to the current velocity.
velocity += deltaVelocity;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lastUpdate = new Date(System.currentTimeMillis());
//give each UI variable a value
tv_lat = findViewById(R.id.tv_lat);
tv_lon = findViewById(R.id.tv_lon);
tv_altitude = findViewById(R.id.tv_altitude);
tv_accuracy = findViewById(R.id.tv_accuracy);
tv_speed = findViewById(R.id.tv_speed);
tv_sensor = findViewById(R.id.tv_sensor);
tv_updates = findViewById(R.id.tv_updates);
tv_address = findViewById(R.id.tv_address);
tv_accel = findViewById(R.id.tv_accel);
sw_locationupdates = findViewById(R.id.sw_locationsupdates);
sw_gps = findViewById(R.id.sw_gps);
//initialize sensor objects
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Timer updateTimer = new Timer("velocityUpdate");
updateTimer.scheduleAtFixedRate(new TimerTask()
public void run()
updateGUI();
, 0, 1000);
//set all properties of LocationRequest
locationRequest = new LocationRequest();
//how often does the default location check occur?
locationRequest.setInterval(1000 * DEFAULT_UPDATE_INTERVAL);
//how often does the default location check occur when set to the most frequent update?
locationRequest.setFastestInterval(1000 * FAST_UPDATE_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//event that is triggered whenever the update interval is met.
locationCallBack = new LocationCallback()
@Override
public void onLocationResult(LocationResult locationResult)
super.onLocationResult(locationResult);
//save the location
Location location = locationResult.getLastLocation();
updateUIValues(location);
;
sw_gps.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if (sw_gps.isChecked())
//most accurate - use GPS
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
tv_sensor.setText("Using GPS sensors");
else
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
tv_sensor.setText("Using Towers + WiFi");
);
sw_locationupdates.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if (sw_locationupdates.isChecked())
//turn on location tracking
startLocationUpdates();
else
//turn off tracking
stopLocationUpdates();
);
updateGPS();
//end onCreate() method
private void updateGUI()
// Convert from meters per second to miles per hour.
final double mph = (Math.round(100*velocity / 1.6 * 3.6))/100;
// Update the GUI
handler.post(new Runnable()
public void run()
tv_speed.setText(String.valueOf(mph) + "mph");
);
private void stopLocationUpdates()
tv_updates.setText("Location is not being tracked");
tv_speed.setText("Not tracking location");
tv_lat.setText("Not tracking location");
tv_lon.setText("Not tracking location");
tv_accuracy.setText("Not tracking location");
tv_altitude.setText("Not tracking location");
tv_address.setText("Not tracking location");
tv_sensor.setText("Not tracking location");
fusedLocationProviderClient.removeLocationUpdates(locationCallBack);
private void startLocationUpdates()
tv_updates.setText("Location is being tracked");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallBack, null);
updateGPS();
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
case PERMISSIONS_FINE_LOCATION:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
updateGPS();
else
Toast.makeText(this, "This app requires permission to be granted in order to work properly.", Toast.LENGTH_SHORT).show();
finish();
break;
private void updateGPS()
//get permission from the user to track GPS
//get the current location from fused client
//update the UI - i.e. set all properties in their associated text view items.
fusedLocationProviderClient= LocationServices.getFusedLocationProviderClient(MainActivity.this);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED)
//user provided the permission
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>()
@Override
public void onSuccess(Location location)
if(location!=null)
//we got permissions
updateUIValues(location);
);
else
//permissions not granted yet
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
requestPermissions(new String[] Manifest.permission.ACCESS_FINE_LOCATION, PERMISSIONS_FINE_LOCATION);
protected void onResume()
super.onResume();
mSensorManager.registerListener(sensorEventListener, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
protected void onPause()
super.onPause();
mSensorManager.unregisterListener(sensorEventListener);
private void updateUIValues(Location location)
//update all the text view objects with a new location.
tv_lat.setText(String.valueOf(location.getLatitude()));
tv_lon.setText(String.valueOf(location.getLongitude()));
tv_accuracy.setText(String.valueOf(location.getAccuracy()));
if(location.hasAltitude())
tv_altitude.setText(String.valueOf(location.getAltitude()));
else
tv_altitude.setText("Not available.");
Geocoder geocoder=new Geocoder(MainActivity.this);
try
List<Address> addresses=geocoder.getFromLocation(location.getLatitude(),location.getLongitude(),1);
tv_address.setText(addresses.get(0).getAddressLine(0));
catch(Exception e)
tv_address.setText("Unable to get street address");
【讨论】:
正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。以上是关于使用内置 android 传感器的移动方向的主要内容,如果未能解决你的问题,请参考以下文章
如何在android的驱动程序中对加速度传感器的数据进行方向和坐标的转