Skip to content

Commit

Permalink
[android-auto] Use compass and location data from car
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Shkrob <andrew.shkrob.social@yandex.by>
  • Loading branch information
AndrewShkrob committed Apr 29, 2024
1 parent 14412d6 commit f2806af
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 15 deletions.
1 change: 1 addition & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ dependencies {
implementation 'androidx.annotation:annotation:1.7.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.car.app:app:1.7.0-alpha02'
implementation 'androidx.car.app:app-projected:1.7.0-alpha02'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.fragment:fragment:1.6.2'
implementation 'androidx.preference:preference:1.2.1'
Expand Down
25 changes: 10 additions & 15 deletions android/app/src/main/java/app/organicmaps/car/CarAppSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import androidx.lifecycle.LifecycleOwner;

import app.organicmaps.Framework;
import app.organicmaps.Map;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.bookmarks.data.MapObject;
Expand All @@ -25,16 +24,14 @@
import app.organicmaps.car.screens.base.BaseMapScreen;
import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder;
import app.organicmaps.car.screens.download.DownloaderHelpers;
import app.organicmaps.car.util.CarSensorsManager;
import app.organicmaps.car.util.CurrentCountryChangedListener;
import app.organicmaps.car.util.IntentUtils;
import app.organicmaps.car.util.ThemeUtils;
import app.organicmaps.display.DisplayChangedListener;
import app.organicmaps.display.DisplayManager;
import app.organicmaps.display.DisplayType;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.location.LocationState;
import app.organicmaps.location.SensorHelper;
import app.organicmaps.location.SensorListener;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.util.Config;
import app.organicmaps.util.LocationUtils;
Expand All @@ -46,7 +43,7 @@
import java.util.List;

public final class CarAppSession extends Session implements DefaultLifecycleObserver,
SensorListener, LocationState.ModeChangeListener, DisplayChangedListener, Framework.PlacePageActivationListener
LocationState.ModeChangeListener, DisplayChangedListener, Framework.PlacePageActivationListener
{
private static final String TAG = CarAppSession.class.getSimpleName();

Expand All @@ -56,6 +53,9 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse
private final SurfaceRenderer mSurfaceRenderer;
@NonNull
private final ScreenManager mScreenManager;
@SuppressWarnings("NotNullFieldNotInitialized")
@NonNull
private CarSensorsManager mSensorsManager;
@NonNull
private final CurrentCountryChangedListener mCurrentCountryChangedListener;
@SuppressWarnings("NotNullFieldNotInitialized")
Expand Down Expand Up @@ -111,6 +111,7 @@ public void onNewIntent(@NonNull Intent intent)
public void onCreate(@NonNull LifecycleOwner owner)
{
Logger.d(TAG);
mSensorsManager = new CarSensorsManager(getCarContext());
mDisplayManager = DisplayManager.from(getCarContext());
mDisplayManager.addListener(DisplayType.Car, this);
init();
Expand All @@ -126,9 +127,8 @@ public void onStart(@NonNull LifecycleOwner owner)
Framework.nativePlacePageActivationListener(this);
mCurrentCountryChangedListener.onStart(getCarContext());
}
SensorHelper.from(getCarContext()).addListener(this);
if (LocationUtils.checkFineLocationPermission(getCarContext()) && !LocationHelper.from(getCarContext()).isActive())
LocationHelper.from(getCarContext()).start();
if (LocationUtils.checkFineLocationPermission(getCarContext()))
mSensorsManager.onStart();

if (mDisplayManager.isCarDisplayUsed())
{
Expand All @@ -141,7 +141,7 @@ public void onStart(@NonNull LifecycleOwner owner)
public void onStop(@NonNull LifecycleOwner owner)
{
Logger.d(TAG);
SensorHelper.from(getCarContext()).removeListener(this);
mSensorsManager.onStop();
if (mDisplayManager.isCarDisplayUsed())
{
LocationState.nativeRemoveListener();
Expand Down Expand Up @@ -182,7 +182,7 @@ private Screen prepareScreens()
screensStack.add(new DownloadMapsScreenBuilder(getCarContext()).setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.FirstLaunch).build());

if (!LocationUtils.checkFineLocationPermission(getCarContext()))
screensStack.add(new RequestPermissionsScreen(getCarContext(), () -> LocationHelper.from(getCarContext()).start()));
screensStack.add(new RequestPermissionsScreen(getCarContext(), mSensorsManager::onStart));

if (mDisplayManager.isDeviceDisplayUsed())
{
Expand All @@ -205,11 +205,6 @@ public void onMyPositionModeChanged(int newMode)
screen.invalidate();
}

public void onCompassUpdated(double north)
{
Map.onCompassUpdated(north, true);
}

@Override
public void onDisplayChangedToDevice(@NonNull Runnable onTaskFinishedCallback)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package app.organicmaps.car.util;

import static android.Manifest.permission.ACCESS_FINE_LOCATION;

import android.location.Location;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresPermission;
import androidx.car.app.CarContext;
import androidx.car.app.hardware.CarHardwareManager;
import androidx.car.app.hardware.common.CarValue;
import androidx.car.app.hardware.info.CarHardwareLocation;
import androidx.car.app.hardware.info.CarSensors;
import androidx.car.app.hardware.info.Compass;
import androidx.core.content.ContextCompat;

import app.organicmaps.Map;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.location.SensorHelper;
import app.organicmaps.util.log.Logger;

import java.util.List;
import java.util.concurrent.Executor;

public class CarSensorsManager
{
private static final String TAG = CarSensorsManager.class.getSimpleName();

@NonNull
private final CarContext mCarContext;
@NonNull
private final CarSensors mCarSensors;

private boolean mIsCarCompassUsed = true;
private boolean mIsCarLocationUsed = true;

public CarSensorsManager(@NonNull final CarContext context)
{
mCarContext = context;
mCarSensors = mCarContext.getCarService(CarHardwareManager.class).getCarSensors();
}

@RequiresPermission(ACCESS_FINE_LOCATION)
public void onStart()
{
final Executor executor = ContextCompat.getMainExecutor(mCarContext);

if (mIsCarCompassUsed)
mCarSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, executor, this::onCarCompassDataAvailable);
else
SensorHelper.from(mCarContext).addListener(this::onCompassUpdated);

if (!LocationHelper.from(mCarContext).isActive())
LocationHelper.from(mCarContext).start();

if (mIsCarLocationUsed)
mCarSensors.addCarHardwareLocationListener(CarSensors.UPDATE_RATE_FASTEST, executor, this::onCarLocationDataAvailable);
}

public void onStop()
{
if (mIsCarCompassUsed)
mCarSensors.removeCompassListener(this::onCarCompassDataAvailable);
else
SensorHelper.from(mCarContext).removeListener(this::onCompassUpdated);

if (mIsCarLocationUsed)
mCarSensors.removeCarHardwareLocationListener(this::onCarLocationDataAvailable);
}

private void onCarCompassDataAvailable(@NonNull final Compass compass)
{
final CarValue<List<Float>> data = compass.getOrientations();
if (data.getStatus() == CarValue.STATUS_UNIMPLEMENTED)
onCarCompassUnsupported();
else if (data.getStatus() == CarValue.STATUS_SUCCESS)
{
final List<Float> orientations = compass.getOrientations().getValue();
if (orientations == null)
return;
final float azimuth = orientations.get(0);
Map.onCompassUpdated(Math.toRadians(azimuth), true);
}
}

private void onCompassUpdated(double north)
{
Map.onCompassUpdated(north, true);
}

private void onCarLocationDataAvailable(@NonNull final CarHardwareLocation hardwareLocation)
{
final CarValue<Location> location = hardwareLocation.getLocation();
if (location.getStatus() == CarValue.STATUS_UNIMPLEMENTED)
onCarLocationUnsupported();
else if (location.getStatus() == CarValue.STATUS_SUCCESS)
{
final Location loc = location.getValue();
if (loc != null)
LocationHelper.from(mCarContext).onLocationChanged(loc);
}
}

private void onCarLocationUnsupported()
{
Logger.d(TAG);
mIsCarLocationUsed = false;
mCarSensors.removeCarHardwareLocationListener(this::onCarLocationDataAvailable);
}

private void onCarCompassUnsupported()
{
Logger.d(TAG);
mIsCarCompassUsed = false;
mCarSensors.removeCompassListener(this::onCarCompassDataAvailable);
SensorHelper.from(mCarContext).addListener(this::onCompassUpdated);
}
}

0 comments on commit f2806af

Please sign in to comment.