mobile orientation using in-built android sensors

Viewed 144

I am a novice in this field. My goal is to make an android application, when in a vehicle, it is used to measure speed of the vehicle using android in-built sensors. The problem I am facing is I can get acceleration using TYPE_LINEAR_ACCELERATION. But it shows on 3 different values of 3 axis. What I can understand is for this application, I should see if the mobile is in horizontal position then I should consider Y axis and if the mobile is in horizontal position then I should take X axis. But how can I know if the mobile is in horizontal or vertical position? Can someone please help me in this?

It is showing me errors, i just copied your given code: 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));
    }

It is showing me errors Cannot resolve symbol "display","rotation","windowManager" Can you tell me how to resolve them?

2 Answers
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
        display?.rotation
    }else{
        windowManager.defaultDisplay.orientation
    }

You can use this to get orientation

 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");
    }
}

}

Related