mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-21 13:53:37 +00:00
[android] Re-format java code by clang-format
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
This commit is contained in:
@@ -8,10 +8,10 @@ import android.app.PendingIntent;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.RequiresPermission;
|
import androidx.annotation.RequiresPermission;
|
||||||
|
import app.organicmaps.sdk.util.LocationUtils;
|
||||||
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
import com.google.android.gms.common.api.ApiException;
|
import com.google.android.gms.common.api.ApiException;
|
||||||
import com.google.android.gms.common.api.ResolvableApiException;
|
import com.google.android.gms.common.api.ResolvableApiException;
|
||||||
import com.google.android.gms.location.FusedLocationProviderClient;
|
import com.google.android.gms.location.FusedLocationProviderClient;
|
||||||
@@ -26,9 +26,6 @@ import com.google.android.gms.location.LocationSettingsStatusCodes;
|
|||||||
import com.google.android.gms.location.Priority;
|
import com.google.android.gms.location.Priority;
|
||||||
import com.google.android.gms.location.SettingsClient;
|
import com.google.android.gms.location.SettingsClient;
|
||||||
|
|
||||||
import app.organicmaps.sdk.util.LocationUtils;
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
|
||||||
|
|
||||||
class GoogleFusedLocationProvider extends BaseLocationProvider
|
class GoogleFusedLocationProvider extends BaseLocationProvider
|
||||||
{
|
{
|
||||||
private static final String TAG = GoogleFusedLocationProvider.class.getSimpleName();
|
private static final String TAG = GoogleFusedLocationProvider.class.getSimpleName();
|
||||||
@@ -72,71 +69,75 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
|
|||||||
{
|
{
|
||||||
Logger.d(TAG);
|
Logger.d(TAG);
|
||||||
|
|
||||||
final LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, interval)
|
final LocationRequest locationRequest =
|
||||||
// Wait a few seconds for accurate locations initially, when accurate locations could not be computed on the device immediately.
|
new LocationRequest
|
||||||
// https://github.com/organicmaps/organicmaps/issues/2149
|
.Builder(Priority.PRIORITY_HIGH_ACCURACY, interval)
|
||||||
.setWaitForAccurateLocation(true)
|
// Wait a few seconds for accurate locations initially, when accurate locations could not be computed on the
|
||||||
// The desired location granularity should correspond to the client permission level. The client will be
|
// device immediately. https://github.com/organicmaps/organicmaps/issues/2149
|
||||||
// delivered fine locations while it has the Manifest.permission.ACCESS_FINE_LOCATION permission, coarse
|
.setWaitForAccurateLocation(true)
|
||||||
// locations while it has only the Manifest.permission.ACCESS_COARSE_LOCATION permission, and no location
|
// The desired location granularity should correspond to the client permission level. The client will be
|
||||||
// if it lacks either.
|
// delivered fine locations while it has the Manifest.permission.ACCESS_FINE_LOCATION permission, coarse
|
||||||
.setGranularity(Granularity.GRANULARITY_PERMISSION_LEVEL)
|
// locations while it has only the Manifest.permission.ACCESS_COARSE_LOCATION permission, and no location
|
||||||
// Sets the maximum age of an initial historical location delivered for this request.
|
// if it lacks either.
|
||||||
.setMaxUpdateAgeMillis(60 * 60 * 1000L) // 1 hour
|
.setGranularity(Granularity.GRANULARITY_PERMISSION_LEVEL)
|
||||||
.build();
|
// Sets the maximum age of an initial historical location delivered for this request.
|
||||||
|
.setMaxUpdateAgeMillis(60 * 60 * 1000L) // 1 hour
|
||||||
|
.build();
|
||||||
|
|
||||||
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
|
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
|
||||||
builder.addLocationRequest(locationRequest);
|
builder.addLocationRequest(locationRequest);
|
||||||
builder.setAlwaysShow(true); // improves the wording/appearance of the dialog
|
builder.setAlwaysShow(true); // improves the wording/appearance of the dialog
|
||||||
final LocationSettingsRequest locationSettingsRequest = builder.build();
|
final LocationSettingsRequest locationSettingsRequest = builder.build();
|
||||||
|
|
||||||
mSettingsClient.checkLocationSettings(locationSettingsRequest).addOnSuccessListener(locationSettingsResponse -> {
|
mSettingsClient.checkLocationSettings(locationSettingsRequest)
|
||||||
Logger.d(TAG, "Service is available");
|
.addOnSuccessListener(locationSettingsResponse -> {
|
||||||
mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper());
|
Logger.d(TAG, "Service is available");
|
||||||
}).addOnFailureListener(e -> {
|
mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper());
|
||||||
try
|
})
|
||||||
{
|
.addOnFailureListener(e -> {
|
||||||
int statusCode = ((ApiException) e).getStatusCode();
|
try
|
||||||
if (statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED)
|
|
||||||
{
|
|
||||||
// This case happens if at least one of the following system settings is off:
|
|
||||||
// 1. Location Services a.k.a GPS;
|
|
||||||
// 2. Google Location Accuracy a.k.a High Accuracy;
|
|
||||||
// 3. Both Wi-Fi && Mobile Data together (needed for 2).
|
|
||||||
//
|
|
||||||
// PendingIntent below will show a special Google "For better experience... enable (1) and/or (2) and/or (3)"
|
|
||||||
// dialog. This system dialog can change system settings if "Yes" is pressed. We can't do it from our app.
|
|
||||||
// However, we don't want to annoy a user who disabled (2) or (3) intentionally. GPS (1) is mandatory to
|
|
||||||
// continue, while (2) and (3) are not dealbreakers here.
|
|
||||||
//
|
|
||||||
// See https://github.com/organicmaps/organicmaps/issues/3846
|
|
||||||
//
|
|
||||||
if (LocationUtils.areLocationServicesTurnedOn(mContext))
|
|
||||||
{
|
{
|
||||||
Logger.d(TAG, "Don't show 'location resolution' dialog because location services are already on");
|
int statusCode = ((ApiException) e).getStatusCode();
|
||||||
mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper());
|
if (statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED)
|
||||||
return;
|
{
|
||||||
|
// This case happens if at least one of the following system settings is off:
|
||||||
|
// 1. Location Services a.k.a GPS;
|
||||||
|
// 2. Google Location Accuracy a.k.a High Accuracy;
|
||||||
|
// 3. Both Wi-Fi && Mobile Data together (needed for 2).
|
||||||
|
//
|
||||||
|
// PendingIntent below will show a special Google "For better experience... enable (1) and/or (2) and/or
|
||||||
|
// (3)" dialog. This system dialog can change system settings if "Yes" is pressed. We can't do it from our
|
||||||
|
// app. However, we don't want to annoy a user who disabled (2) or (3) intentionally. GPS (1) is mandatory
|
||||||
|
// to continue, while (2) and (3) are not dealbreakers here.
|
||||||
|
//
|
||||||
|
// See https://github.com/organicmaps/organicmaps/issues/3846
|
||||||
|
//
|
||||||
|
if (LocationUtils.areLocationServicesTurnedOn(mContext))
|
||||||
|
{
|
||||||
|
Logger.d(TAG, "Don't show 'location resolution' dialog because location services are already on");
|
||||||
|
mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Logger.d(TAG, "Requesting 'location resolution' dialog");
|
||||||
|
final ResolvableApiException resolvable = (ResolvableApiException) e;
|
||||||
|
final PendingIntent pendingIntent = resolvable.getResolution();
|
||||||
|
// Call this callback in the next event loop to allow LocationHelper::start() to finish.
|
||||||
|
runLater(() -> mListener.onLocationResolutionRequired(pendingIntent));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Logger.d(TAG, "Requesting 'location resolution' dialog");
|
catch (ClassCastException ex)
|
||||||
final ResolvableApiException resolvable = (ResolvableApiException) e;
|
{
|
||||||
final PendingIntent pendingIntent = resolvable.getResolution();
|
// Ignore, should be an impossible error.
|
||||||
|
// https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
|
||||||
|
Logger.e(TAG, "An error that should be impossible: " + ex);
|
||||||
|
}
|
||||||
|
// Location settings are not satisfied. However, we have no way to fix the
|
||||||
|
// settings so we won't show the dialog.
|
||||||
|
Logger.e(TAG, "Service is not available: " + e);
|
||||||
// Call this callback in the next event loop to allow LocationHelper::start() to finish.
|
// Call this callback in the next event loop to allow LocationHelper::start() to finish.
|
||||||
runLater(() -> mListener.onLocationResolutionRequired(pendingIntent));
|
runLater(mListener::onFusedLocationUnsupported);
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ClassCastException ex)
|
|
||||||
{
|
|
||||||
// Ignore, should be an impossible error.
|
|
||||||
// https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
|
|
||||||
Logger.e(TAG, "An error that should be impossible: " + ex);
|
|
||||||
}
|
|
||||||
// Location settings are not satisfied. However, we have no way to fix the
|
|
||||||
// settings so we won't show the dialog.
|
|
||||||
Logger.e(TAG, "Service is not available: " + e);
|
|
||||||
// Call this callback in the next event loop to allow LocationHelper::start() to finish.
|
|
||||||
runLater(mListener::onFusedLocationUnsupported);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package app.organicmaps.sdk.location;
|
package app.organicmaps.sdk.location;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import com.google.android.gms.common.ConnectionResult;
|
|
||||||
import com.google.android.gms.common.GoogleApiAvailability;
|
|
||||||
|
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
|
import com.google.android.gms.common.GoogleApiAvailability;
|
||||||
|
|
||||||
public class LocationProviderFactory
|
public class LocationProviderFactory
|
||||||
{
|
{
|
||||||
@@ -18,7 +16,8 @@ public class LocationProviderFactory
|
|||||||
return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS;
|
return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BaseLocationProvider getProvider(@NonNull Context context, @NonNull BaseLocationProvider.Listener listener)
|
public static BaseLocationProvider getProvider(@NonNull Context context,
|
||||||
|
@NonNull BaseLocationProvider.Listener listener)
|
||||||
{
|
{
|
||||||
if (isGoogleLocationAvailable(context) && Config.useGoogleServices())
|
if (isGoogleLocationAvailable(context) && Config.useGoogleServices())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,10 +5,16 @@ import android.content.res.Resources;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import app.organicmaps.sdk.Framework;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.ElevationInfo;
|
||||||
|
import app.organicmaps.util.ThemeUtils;
|
||||||
|
import app.organicmaps.util.Utils;
|
||||||
|
import app.organicmaps.widget.placepage.AxisValueFormatter;
|
||||||
|
import app.organicmaps.widget.placepage.CurrentLocationMarkerView;
|
||||||
|
import app.organicmaps.widget.placepage.FloatingMarkerView;
|
||||||
import com.github.mikephil.charting.charts.LineChart;
|
import com.github.mikephil.charting.charts.LineChart;
|
||||||
import com.github.mikephil.charting.components.Legend;
|
import com.github.mikephil.charting.components.Legend;
|
||||||
import com.github.mikephil.charting.components.MarkerView;
|
import com.github.mikephil.charting.components.MarkerView;
|
||||||
@@ -20,16 +26,6 @@ import com.github.mikephil.charting.data.LineDataSet;
|
|||||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||||
import com.github.mikephil.charting.highlight.Highlight;
|
import com.github.mikephil.charting.highlight.Highlight;
|
||||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||||
|
|
||||||
import app.organicmaps.sdk.Framework;
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.ElevationInfo;
|
|
||||||
import app.organicmaps.widget.placepage.AxisValueFormatter;
|
|
||||||
import app.organicmaps.widget.placepage.CurrentLocationMarkerView;
|
|
||||||
import app.organicmaps.widget.placepage.FloatingMarkerView;
|
|
||||||
import app.organicmaps.util.ThemeUtils;
|
|
||||||
import app.organicmaps.util.Utils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -151,7 +147,7 @@ public class ChartController implements OnChartValueSelectedListener,
|
|||||||
mTrackId = info.getId();
|
mTrackId = info.getId();
|
||||||
List<Entry> values = new ArrayList<>();
|
List<Entry> values = new ArrayList<>();
|
||||||
|
|
||||||
for (ElevationInfo.Point point: info.getPoints())
|
for (ElevationInfo.Point point : info.getPoints())
|
||||||
values.add(new Entry((float) point.getDistance(), point.getAltitude()));
|
values.add(new Entry((float) point.getDistance(), point.getAltitude()));
|
||||||
|
|
||||||
LineDataSet set = new LineDataSet(values, "Elevation_profile_points");
|
LineDataSet set = new LineDataSet(values, "Elevation_profile_points");
|
||||||
@@ -184,15 +180,15 @@ public class ChartController implements OnChartValueSelectedListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValueSelected(Entry e, Highlight h) {
|
public void onValueSelected(Entry e, Highlight h)
|
||||||
|
{
|
||||||
mFloatingMarkerView.updateOffsets(e, h);
|
mFloatingMarkerView.updateOffsets(e, h);
|
||||||
Highlight curPos = getCurrentPosHighlight();
|
Highlight curPos = getCurrentPosHighlight();
|
||||||
|
|
||||||
if (mCurrentPositionOutOfTrack)
|
if (mCurrentPositionOutOfTrack)
|
||||||
mChart.highlightValues(Collections.singletonList(h), Collections.singletonList(mFloatingMarkerView));
|
mChart.highlightValues(Collections.singletonList(h), Collections.singletonList(mFloatingMarkerView));
|
||||||
else
|
else
|
||||||
mChart.highlightValues(Arrays.asList(curPos, h), Arrays.asList(mCurrentLocationMarkerView,
|
mChart.highlightValues(Arrays.asList(curPos, h), Arrays.asList(mCurrentLocationMarkerView, mFloatingMarkerView));
|
||||||
mFloatingMarkerView));
|
|
||||||
if (mTrackId == Utils.INVALID_ID)
|
if (mTrackId == Utils.INVALID_ID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import android.location.Location;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
@@ -28,10 +27,10 @@ import androidx.annotation.StringRes;
|
|||||||
import androidx.annotation.StyleRes;
|
import androidx.annotation.StyleRes;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import app.organicmaps.base.BaseMwmFragmentActivity;
|
import app.organicmaps.base.BaseMwmFragmentActivity;
|
||||||
|
import app.organicmaps.intent.Factory;
|
||||||
import app.organicmaps.sdk.Framework;
|
import app.organicmaps.sdk.Framework;
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
import app.organicmaps.sdk.downloader.MapManager;
|
import app.organicmaps.sdk.downloader.MapManager;
|
||||||
import app.organicmaps.intent.Factory;
|
|
||||||
import app.organicmaps.sdk.location.LocationListener;
|
import app.organicmaps.sdk.location.LocationListener;
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
import app.organicmaps.sdk.util.ConnectionState;
|
import app.organicmaps.sdk.util.ConnectionState;
|
||||||
@@ -39,13 +38,11 @@ import app.organicmaps.sdk.util.StringUtils;
|
|||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
||||||
|
|
||||||
import com.google.android.material.button.MaterialButton;
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -81,8 +78,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
private int mCountryDownloadListenerSlot;
|
private int mCountryDownloadListenerSlot;
|
||||||
|
|
||||||
private final LocationListener mLocationListener = new LocationListener()
|
private final LocationListener mLocationListener = new LocationListener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onLocationUpdated(Location location)
|
public void onLocationUpdated(Location location)
|
||||||
{
|
{
|
||||||
@@ -117,34 +113,33 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final app.organicmaps.sdk.DownloadResourcesLegacyActivity.Listener mResourcesDownloadListener = new app.organicmaps.sdk.DownloadResourcesLegacyActivity.Listener()
|
private final app.organicmaps.sdk.DownloadResourcesLegacyActivity.Listener mResourcesDownloadListener =
|
||||||
{
|
new app.organicmaps.sdk.DownloadResourcesLegacyActivity.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onProgress(final int percent)
|
public void onProgress(final int percent)
|
||||||
{
|
{
|
||||||
if (!isFinishing())
|
if (!isFinishing())
|
||||||
mProgress.setProgressCompat(percent, true);
|
mProgress.setProgressCompat(percent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFinish(final int errorCode)
|
public void onFinish(final int errorCode)
|
||||||
{
|
{
|
||||||
if (isFinishing())
|
if (isFinishing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (errorCode == ERR_DOWNLOAD_SUCCESS)
|
if (errorCode == ERR_DOWNLOAD_SUCCESS)
|
||||||
{
|
{
|
||||||
final int res = nativeStartNextFileDownload(mResourcesDownloadListener);
|
final int res = nativeStartNextFileDownload(mResourcesDownloadListener);
|
||||||
if (res == ERR_NO_MORE_FILES)
|
if (res == ERR_NO_MORE_FILES)
|
||||||
finishFilesDownload(res);
|
finishFilesDownload(res);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
finishFilesDownload(errorCode);
|
finishFilesDownload(errorCode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final MapManager.StorageCallback mCountryDownloadListener = new MapManager.StorageCallback()
|
private final MapManager.StorageCallback mCountryDownloadListener = new MapManager.StorageCallback() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||||
{
|
{
|
||||||
@@ -155,14 +150,14 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
switch (item.newStatus)
|
switch (item.newStatus)
|
||||||
{
|
{
|
||||||
case CountryItem.STATUS_DONE:
|
case CountryItem.STATUS_DONE:
|
||||||
mAreResourcesDownloaded = true;
|
mAreResourcesDownloaded = true;
|
||||||
showMap();
|
showMap();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CountryItem.STATUS_FAILED:
|
case CountryItem.STATUS_FAILED:
|
||||||
MapManager.showError(DownloadResourcesLegacyActivity.this, item, null);
|
MapManager.showError(DownloadResourcesLegacyActivity.this, item, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,8 +232,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
private void setDownloadMessage(int bytesToDownload)
|
private void setDownloadMessage(int bytesToDownload)
|
||||||
{
|
{
|
||||||
mTvMessage.setText(getString(R.string.download_resources,
|
mTvMessage.setText(getString(R.string.download_resources, StringUtils.getFileSizeString(this, bytesToDownload)));
|
||||||
StringUtils.getFileSizeString(this, bytesToDownload)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean prepareFilesDownload(boolean showMap)
|
private boolean prepareFilesDownload(boolean showMap)
|
||||||
@@ -375,7 +369,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
CountryItem item = CountryItem.fill(mCurrentCountry);
|
CountryItem item = CountryItem.fill(mCurrentCountry);
|
||||||
String fileSizeString = StringUtils.getFileSizeString(this, item.totalSize);
|
String fileSizeString = StringUtils.getFileSizeString(this, item.totalSize);
|
||||||
mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString));
|
mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString));
|
||||||
mProgress.setMax((int)item.totalSize);
|
mProgress.setMax((int) item.totalSize);
|
||||||
mProgress.setProgressCompat(0, true);
|
mProgress.setProgressCompat(0, true);
|
||||||
|
|
||||||
mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener);
|
mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener);
|
||||||
@@ -399,8 +393,10 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
if (mAlertDialog != null && mAlertDialog.isShowing())
|
if (mAlertDialog != null && mAlertDialog.isShowing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@StringRes final int titleId;
|
@StringRes
|
||||||
@StringRes final int messageId = switch (result)
|
final int titleId;
|
||||||
|
@StringRes
|
||||||
|
final int messageId = switch (result)
|
||||||
{
|
{
|
||||||
case ERR_NOT_ENOUGH_FREE_SPACE ->
|
case ERR_NOT_ENOUGH_FREE_SPACE ->
|
||||||
{
|
{
|
||||||
@@ -415,8 +411,8 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
case ERR_DOWNLOAD_ERROR ->
|
case ERR_DOWNLOAD_ERROR ->
|
||||||
{
|
{
|
||||||
titleId = R.string.connection_failure;
|
titleId = R.string.connection_failure;
|
||||||
yield (ConnectionState.INSTANCE.isConnected() ? R.string.download_has_failed
|
yield(ConnectionState.INSTANCE.isConnected() ? R.string.download_has_failed
|
||||||
: R.string.common_check_internet_connection_dialog);
|
: R.string.common_check_internet_connection_dialog);
|
||||||
}
|
}
|
||||||
case ERR_DISK_ERROR ->
|
case ERR_DISK_ERROR ->
|
||||||
{
|
{
|
||||||
@@ -426,17 +422,18 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
|||||||
default -> throw new AssertionError("Unexpected result code = " + result);
|
default -> throw new AssertionError("Unexpected result code = " + result);
|
||||||
};
|
};
|
||||||
|
|
||||||
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
||||||
.setTitle(titleId)
|
.setTitle(titleId)
|
||||||
.setMessage(messageId)
|
.setMessage(messageId)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setOnCancelListener((dialog) -> setAction(PAUSE))
|
.setOnCancelListener((dialog) -> setAction(PAUSE))
|
||||||
.setPositiveButton(R.string.try_again, (dialog, which) -> {
|
.setPositiveButton(R.string.try_again,
|
||||||
setAction(TRY_AGAIN);
|
(dialog, which) -> {
|
||||||
onTryAgainClicked();
|
setAction(TRY_AGAIN);
|
||||||
})
|
onTryAgainClicked();
|
||||||
.setOnDismissListener(dialog -> mAlertDialog = null)
|
})
|
||||||
.show();
|
.setOnDismissListener(dialog -> mAlertDialog = null)
|
||||||
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -10,17 +10,14 @@ import android.view.SurfaceHolder;
|
|||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.content.res.ConfigurationHelper;
|
import androidx.core.content.res.ConfigurationHelper;
|
||||||
|
|
||||||
import app.organicmaps.base.BaseMwmFragment;
|
import app.organicmaps.base.BaseMwmFragment;
|
||||||
import app.organicmaps.sdk.display.DisplayType;
|
|
||||||
import app.organicmaps.sdk.Map;
|
import app.organicmaps.sdk.Map;
|
||||||
import app.organicmaps.sdk.MapRenderingListener;
|
import app.organicmaps.sdk.MapRenderingListener;
|
||||||
|
import app.organicmaps.sdk.display.DisplayType;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
public class MapFragment extends BaseMwmFragment implements View.OnTouchListener, SurfaceHolder.Callback
|
public class MapFragment extends BaseMwmFragment implements View.OnTouchListener, SurfaceHolder.Callback
|
||||||
@@ -71,7 +68,8 @@ public class MapFragment extends BaseMwmFragment implements View.OnTouchListener
|
|||||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height)
|
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height)
|
||||||
{
|
{
|
||||||
Logger.d(TAG);
|
Logger.d(TAG);
|
||||||
mMap.onSurfaceChanged(requireContext(), surfaceHolder.getSurface(), surfaceHolder.getSurfaceFrame(), surfaceHolder.isCreating());
|
mMap.onSurfaceChanged(requireContext(), surfaceHolder.getSurface(), surfaceHolder.getSurfaceFrame(),
|
||||||
|
surfaceHolder.isCreating());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ package app.organicmaps;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.organicmaps.base.BaseMwmFragmentActivity;
|
import app.organicmaps.base.BaseMwmFragmentActivity;
|
||||||
import app.organicmaps.sdk.display.DisplayChangedListener;
|
import app.organicmaps.sdk.display.DisplayChangedListener;
|
||||||
import app.organicmaps.sdk.display.DisplayManager;
|
import app.organicmaps.sdk.display.DisplayManager;
|
||||||
@@ -34,8 +32,7 @@ public class MapPlaceholderActivity extends BaseMwmFragmentActivity implements D
|
|||||||
public void onDisplayChangedToDevice(@NonNull Runnable onTaskFinishedCallback)
|
public void onDisplayChangedToDevice(@NonNull Runnable onTaskFinishedCallback)
|
||||||
{
|
{
|
||||||
mRemoveDisplayListener = false;
|
mRemoveDisplayListener = false;
|
||||||
startActivity(new Intent(this, MwmActivity.class)
|
startActivity(new Intent(this, MwmActivity.class).putExtra(MwmActivity.EXTRA_UPDATE_THEME, true));
|
||||||
.putExtra(MwmActivity.EXTRA_UPDATE_THEME, true));
|
|
||||||
finish();
|
finish();
|
||||||
onTaskFinishedCallback.run();
|
onTaskFinishedCallback.run();
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,6 @@ import android.app.Application;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
@@ -15,30 +14,28 @@ import androidx.lifecycle.DefaultLifecycleObserver;
|
|||||||
import androidx.lifecycle.LifecycleObserver;
|
import androidx.lifecycle.LifecycleObserver;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.ProcessLifecycleOwner;
|
import androidx.lifecycle.ProcessLifecycleOwner;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
|
|
||||||
import app.organicmaps.background.OsmUploadWork;
|
import app.organicmaps.background.OsmUploadWork;
|
||||||
import app.organicmaps.downloader.Android7RootCertificateWorkaround;
|
import app.organicmaps.downloader.Android7RootCertificateWorkaround;
|
||||||
import app.organicmaps.downloader.DownloaderNotifier;
|
import app.organicmaps.downloader.DownloaderNotifier;
|
||||||
import app.organicmaps.sdk.display.DisplayManager;
|
import app.organicmaps.location.TrackRecordingService;
|
||||||
|
import app.organicmaps.routing.NavigationService;
|
||||||
|
import app.organicmaps.routing.RoutingController;
|
||||||
import app.organicmaps.sdk.Map;
|
import app.organicmaps.sdk.Map;
|
||||||
|
import app.organicmaps.sdk.OrganicMaps;
|
||||||
|
import app.organicmaps.sdk.display.DisplayManager;
|
||||||
import app.organicmaps.sdk.location.LocationHelper;
|
import app.organicmaps.sdk.location.LocationHelper;
|
||||||
import app.organicmaps.sdk.location.LocationState;
|
import app.organicmaps.sdk.location.LocationState;
|
||||||
import app.organicmaps.sdk.location.SensorHelper;
|
import app.organicmaps.sdk.location.SensorHelper;
|
||||||
import app.organicmaps.sdk.location.TrackRecorder;
|
import app.organicmaps.sdk.location.TrackRecorder;
|
||||||
import app.organicmaps.location.TrackRecordingService;
|
|
||||||
import app.organicmaps.sdk.maplayer.isolines.IsolinesManager;
|
import app.organicmaps.sdk.maplayer.isolines.IsolinesManager;
|
||||||
import app.organicmaps.sdk.maplayer.subway.SubwayManager;
|
import app.organicmaps.sdk.maplayer.subway.SubwayManager;
|
||||||
import app.organicmaps.routing.NavigationService;
|
|
||||||
import app.organicmaps.routing.RoutingController;
|
|
||||||
import app.organicmaps.sdk.OrganicMaps;
|
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
import app.organicmaps.sdk.util.ConnectionState;
|
import app.organicmaps.sdk.util.ConnectionState;
|
||||||
import app.organicmaps.util.Utils;
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
import app.organicmaps.sdk.util.log.LogsManager;
|
import app.organicmaps.sdk.util.log.LogsManager;
|
||||||
|
import app.organicmaps.util.Utils;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
public class MwmApplication extends Application implements Application.ActivityLifecycleCallbacks
|
public class MwmApplication extends Application implements Application.ActivityLifecycleCallbacks
|
||||||
{
|
{
|
||||||
@@ -146,8 +143,7 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private final LifecycleObserver mProcessLifecycleObserver = new DefaultLifecycleObserver()
|
private final LifecycleObserver mProcessLifecycleObserver = new DefaultLifecycleObserver() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart(@NonNull LifecycleOwner owner)
|
public void onStart(@NonNull LifecycleOwner owner)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,21 +5,19 @@ import android.animation.ValueAnimator;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.AccelerateInterpolator;
|
import android.view.animation.AccelerateInterpolator;
|
||||||
|
|
||||||
import androidx.annotation.IntegerRes;
|
import androidx.annotation.IntegerRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import org.chromium.base.ObserverList;
|
|
||||||
|
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
import org.chromium.base.ObserverList;
|
||||||
|
|
||||||
class PanelAnimator
|
class PanelAnimator
|
||||||
{
|
{
|
||||||
private final MwmActivity mActivity;
|
private final MwmActivity mActivity;
|
||||||
private final ObserverList<MwmActivity.LeftAnimationTrackListener> mAnimationTrackListeners = new ObserverList<>();
|
private final ObserverList<MwmActivity.LeftAnimationTrackListener> mAnimationTrackListeners = new ObserverList<>();
|
||||||
private final ObserverList.RewindableIterator<MwmActivity.LeftAnimationTrackListener> mAnimationTrackIterator = mAnimationTrackListeners.rewindableIterator();
|
private final ObserverList.RewindableIterator<MwmActivity.LeftAnimationTrackListener> mAnimationTrackIterator =
|
||||||
|
mAnimationTrackListeners.rewindableIterator();
|
||||||
private final View mPanel;
|
private final View mPanel;
|
||||||
private final int mWidth;
|
private final int mWidth;
|
||||||
@IntegerRes
|
@IntegerRes
|
||||||
@@ -50,7 +48,8 @@ class PanelAnimator
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @param completionListener will be called before the fragment becomes actually visible */
|
/** @param completionListener will be called before the fragment becomes actually visible */
|
||||||
public void show(final Class<? extends Fragment> clazz, final Bundle args, @Nullable final Runnable completionListener)
|
public void show(final Class<? extends Fragment> clazz, final Bundle args,
|
||||||
|
@Nullable final Runnable completionListener)
|
||||||
{
|
{
|
||||||
if (isVisible())
|
if (isVisible())
|
||||||
{
|
{
|
||||||
@@ -78,8 +77,7 @@ class PanelAnimator
|
|||||||
|
|
||||||
ValueAnimator animator = ValueAnimator.ofFloat(-mWidth, 0.0f);
|
ValueAnimator animator = ValueAnimator.ofFloat(-mWidth, 0.0f);
|
||||||
animator.addUpdateListener(this::track);
|
animator.addUpdateListener(this::track);
|
||||||
animator.addListener(new UiUtils.SimpleAnimatorListener()
|
animator.addListener(new UiUtils.SimpleAnimatorListener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation)
|
public void onAnimationEnd(Animator animation)
|
||||||
{
|
{
|
||||||
@@ -109,8 +107,7 @@ class PanelAnimator
|
|||||||
|
|
||||||
ValueAnimator animator = ValueAnimator.ofFloat(0.0f, -mWidth);
|
ValueAnimator animator = ValueAnimator.ofFloat(0.0f, -mWidth);
|
||||||
animator.addUpdateListener(this::track);
|
animator.addUpdateListener(this::track);
|
||||||
animator.addListener(new UiUtils.SimpleAnimatorListener()
|
animator.addListener(new UiUtils.SimpleAnimatorListener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation)
|
public void onAnimationEnd(Animator animation)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.Keep;
|
import androidx.annotation.Keep;
|
||||||
@@ -21,20 +20,18 @@ import androidx.core.graphics.Insets;
|
|||||||
import androidx.core.view.OnApplyWindowInsetsListener;
|
import androidx.core.view.OnApplyWindowInsetsListener;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
import app.organicmaps.sdk.display.DisplayManager;
|
|
||||||
import app.organicmaps.downloader.DownloaderActivity;
|
import app.organicmaps.downloader.DownloaderActivity;
|
||||||
import app.organicmaps.intent.Factory;
|
import app.organicmaps.intent.Factory;
|
||||||
|
import app.organicmaps.sdk.display.DisplayManager;
|
||||||
import app.organicmaps.sdk.location.LocationHelper;
|
import app.organicmaps.sdk.location.LocationHelper;
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
import app.organicmaps.sdk.util.LocationUtils;
|
import app.organicmaps.sdk.util.LocationUtils;
|
||||||
|
import app.organicmaps.sdk.util.concurrency.UiThread;
|
||||||
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
import app.organicmaps.util.SharingUtils;
|
import app.organicmaps.util.SharingUtils;
|
||||||
import app.organicmaps.util.ThemeUtils;
|
import app.organicmaps.util.ThemeUtils;
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.sdk.util.concurrency.UiThread;
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -86,7 +83,7 @@ public class SplashActivity extends AppCompatActivity
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
mPermissionRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(),
|
mPermissionRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(),
|
||||||
result -> Config.setLocationRequested());
|
result -> Config.setLocationRequested());
|
||||||
mApiRequest = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
mApiRequest = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
||||||
setResult(result.getResultCode(), result.getData());
|
setResult(result.getResultCode(), result.getData());
|
||||||
finish();
|
finish();
|
||||||
@@ -109,10 +106,7 @@ public class SplashActivity extends AppCompatActivity
|
|||||||
if (!Config.isLocationRequested() && !LocationUtils.checkLocationPermission(this))
|
if (!Config.isLocationRequested() && !LocationUtils.checkLocationPermission(this))
|
||||||
{
|
{
|
||||||
Logger.d(TAG, "Requesting location permissions");
|
Logger.d(TAG, "Requesting location permissions");
|
||||||
mPermissionRequest.launch(new String[]{
|
mPermissionRequest.launch(new String[] {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION});
|
||||||
ACCESS_COARSE_LOCATION,
|
|
||||||
ACCESS_FINE_LOCATION
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,19 +134,13 @@ public class SplashActivity extends AppCompatActivity
|
|||||||
{
|
{
|
||||||
mCanceled = true;
|
mCanceled = true;
|
||||||
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
|
||||||
.setTitle(titleId)
|
.setTitle(titleId)
|
||||||
.setMessage(messageId)
|
.setMessage(messageId)
|
||||||
.setPositiveButton(
|
.setPositiveButton(
|
||||||
R.string.report_a_bug,
|
R.string.report_a_bug,
|
||||||
(dialog, which) -> Utils.sendBugReport(
|
(dialog, which) -> Utils.sendBugReport(mShareLauncher, this, "Fatal Error", Log.getStackTraceString(error)))
|
||||||
mShareLauncher,
|
.setCancelable(false)
|
||||||
this,
|
.show();
|
||||||
"Fatal Error",
|
|
||||||
Log.getStackTraceString(error)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setCancelable(false)
|
|
||||||
.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
@@ -162,7 +150,8 @@ public class SplashActivity extends AppCompatActivity
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
asyncContinue = app.initOrganicMaps(this::processNavigation);
|
asyncContinue = app.initOrganicMaps(this::processNavigation);
|
||||||
} catch (IOException error)
|
}
|
||||||
|
catch (IOException error)
|
||||||
{
|
{
|
||||||
showFatalErrorDialog(R.string.dialog_error_storage_title, R.string.dialog_error_storage_message, error);
|
showFatalErrorDialog(R.string.dialog_error_storage_title, R.string.dialog_error_storage_message, error);
|
||||||
return;
|
return;
|
||||||
@@ -195,9 +184,12 @@ public class SplashActivity extends AppCompatActivity
|
|||||||
// https://github.com/organicmaps/organicmaps/issues/6944
|
// https://github.com/organicmaps/organicmaps/issues/6944
|
||||||
final Intent intent = Objects.requireNonNull(getIntent());
|
final Intent intent = Objects.requireNonNull(getIntent());
|
||||||
|
|
||||||
if (isManageSpaceActivity(intent)) {
|
if (isManageSpaceActivity(intent))
|
||||||
|
{
|
||||||
intent.setComponent(new ComponentName(this, DownloaderActivity.class));
|
intent.setComponent(new ComponentName(this, DownloaderActivity.class));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
intent.setComponent(new ComponentName(this, DownloadResourcesLegacyActivity.class));
|
intent.setComponent(new ComponentName(this, DownloadResourcesLegacyActivity.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,11 +211,14 @@ public class SplashActivity extends AppCompatActivity
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isManageSpaceActivity(Intent intent) {
|
private boolean isManageSpaceActivity(Intent intent)
|
||||||
|
{
|
||||||
var component = intent.getComponent();
|
var component = intent.getComponent();
|
||||||
|
|
||||||
if (!Intent.ACTION_VIEW.equals(intent.getAction())) return false;
|
if (!Intent.ACTION_VIEW.equals(intent.getAction()))
|
||||||
if (component == null) return false;
|
return false;
|
||||||
|
if (component == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
var manageSpaceActivityName = BuildConfig.APPLICATION_ID + ".ManageSpaceActivity";
|
var manageSpaceActivityName = BuildConfig.APPLICATION_ID + ".ManageSpaceActivity";
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ import android.net.Uri;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import app.organicmaps.base.OnBackPressListener;
|
import app.organicmaps.base.OnBackPressListener;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
|
||||||
@@ -21,8 +19,7 @@ public abstract class WebContainerDelegate implements OnBackPressListener
|
|||||||
@SuppressLint("SetJavaScriptEnabled")
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
private void initWebView(String url)
|
private void initWebView(String url)
|
||||||
{
|
{
|
||||||
mWebView.setWebViewClient(new WebViewClient()
|
mWebView.setWebViewClient(new WebViewClient() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageFinished(WebView view, String url)
|
public void onPageFinished(WebView view, String url)
|
||||||
{
|
{
|
||||||
@@ -37,7 +34,7 @@ public abstract class WebContainerDelegate implements OnBackPressListener
|
|||||||
{
|
{
|
||||||
MailTo parser = MailTo.parse(url);
|
MailTo parser = MailTo.parse(url);
|
||||||
doStartActivity(new Intent(Intent.ACTION_SEND)
|
doStartActivity(new Intent(Intent.ACTION_SEND)
|
||||||
.putExtra(Intent.EXTRA_EMAIL, new String[] { parser.getTo() })
|
.putExtra(Intent.EXTRA_EMAIL, new String[] {parser.getTo()})
|
||||||
.putExtra(Intent.EXTRA_TEXT, parser.getBody())
|
.putExtra(Intent.EXTRA_TEXT, parser.getBody())
|
||||||
.putExtra(Intent.EXTRA_SUBJECT, parser.getSubject())
|
.putExtra(Intent.EXTRA_SUBJECT, parser.getSubject())
|
||||||
.putExtra(Intent.EXTRA_CC, parser.getCc())
|
.putExtra(Intent.EXTRA_CC, parser.getCc())
|
||||||
@@ -46,8 +43,7 @@ public abstract class WebContainerDelegate implements OnBackPressListener
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
doStartActivity(new Intent(Intent.ACTION_VIEW)
|
doStartActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url)));
|
||||||
.setData(Uri.parse(url)));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,18 +4,23 @@ import android.content.Context;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.SimpleExpandableListAdapter;
|
import android.widget.SimpleExpandableListAdapter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables child selections, also fixes bug with SimpleExpandableListAdapter not switching expandedGroupLayout and collapsedGroupLayout correctly.
|
* Disables child selections, also fixes bug with SimpleExpandableListAdapter not switching expandedGroupLayout and
|
||||||
|
* collapsedGroupLayout correctly.
|
||||||
*/
|
*/
|
||||||
public class DisabledChildSimpleExpandableListAdapter extends SimpleExpandableListAdapter
|
public class DisabledChildSimpleExpandableListAdapter extends SimpleExpandableListAdapter
|
||||||
{
|
{
|
||||||
public DisabledChildSimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo)
|
public DisabledChildSimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData,
|
||||||
|
int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom,
|
||||||
|
int[] groupTo,
|
||||||
|
List<? extends List<? extends Map<String, ?>>> childData,
|
||||||
|
int childLayout, String[] childFrom, int[] childTo)
|
||||||
{
|
{
|
||||||
super(context, groupData, expandedGroupLayout, collapsedGroupLayout, groupFrom, groupTo, childData, childLayout, childFrom, childTo);
|
super(context, groupData, expandedGroupLayout, collapsedGroupLayout, groupFrom, groupTo, childData, childLayout,
|
||||||
|
childFrom, childTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -29,8 +34,7 @@ public class DisabledChildSimpleExpandableListAdapter extends SimpleExpandableLi
|
|||||||
* See http://stackoverflow.com/questions/19520037/simpleexpandablelistadapter-and-expandedgrouplayout for details
|
* See http://stackoverflow.com/questions/19520037/simpleexpandablelistadapter-and-expandedgrouplayout for details
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
|
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
|
||||||
ViewGroup parent)
|
|
||||||
{
|
{
|
||||||
return super.getGroupView(groupPosition, isExpanded, null, parent);
|
return super.getGroupView(groupPosition, isExpanded, null, parent);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.adapter;
|
package app.organicmaps.adapter;
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
public interface OnItemClickListener<T>
|
public interface OnItemClickListener<T>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.background;
|
package app.organicmaps.background;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.work.Constraints;
|
import androidx.work.Constraints;
|
||||||
import androidx.work.NetworkType;
|
import androidx.work.NetworkType;
|
||||||
@@ -17,7 +16,6 @@ import app.organicmaps.sdk.util.log.Logger;
|
|||||||
|
|
||||||
public class OsmUploadWork extends Worker
|
public class OsmUploadWork extends Worker
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final String TAG = OsmUploadWork.class.getSimpleName();
|
private static final String TAG = OsmUploadWork.class.getSimpleName();
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final WorkerParameters mWorkerParameters;
|
private final WorkerParameters mWorkerParameters;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package app.organicmaps.backup;
|
package app.organicmaps.backup;
|
||||||
|
|
||||||
|
import static app.organicmaps.sdk.util.StorageUtils.isFolderWritable;
|
||||||
import static app.organicmaps.settings.BackupSettingsFragment.MAX_BACKUPS_DEFAULT_COUNT;
|
import static app.organicmaps.settings.BackupSettingsFragment.MAX_BACKUPS_DEFAULT_COUNT;
|
||||||
import static app.organicmaps.settings.BackupSettingsFragment.MAX_BACKUPS_KEY;
|
import static app.organicmaps.settings.BackupSettingsFragment.MAX_BACKUPS_KEY;
|
||||||
import static app.organicmaps.sdk.util.StorageUtils.isFolderWritable;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
@@ -12,25 +12,23 @@ import android.text.SpannableStringBuilder;
|
|||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.style.AbsoluteSizeSpan;
|
import android.text.style.AbsoluteSizeSpan;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.documentfile.provider.DocumentFile;
|
import androidx.documentfile.provider.DocumentFile;
|
||||||
|
import app.organicmaps.R;
|
||||||
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
|
||||||
|
|
||||||
public class BackupUtils
|
public class BackupUtils
|
||||||
{
|
{
|
||||||
private static final String BACKUP_PREFIX = "backup_";
|
private static final String BACKUP_PREFIX = "backup_";
|
||||||
private static final String BACKUP_EXTENSION = ".kmz";
|
private static final String BACKUP_EXTENSION = ".kmz";
|
||||||
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").withLocale(Locale.US);
|
private static final DateTimeFormatter DATE_FORMATTER =
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").withLocale(Locale.US);
|
||||||
private static final String TAG = BackupUtils.class.getSimpleName();
|
private static final String TAG = BackupUtils.class.getSimpleName();
|
||||||
|
|
||||||
public static CharSequence formatReadableFolderPath(Context context, @NonNull Uri uri)
|
public static CharSequence formatReadableFolderPath(Context context, @NonNull Uri uri)
|
||||||
@@ -57,8 +55,10 @@ public class BackupUtils
|
|||||||
volumeName = context.getString(R.string.maps_storage_removable);
|
volumeName = context.getString(R.string.maps_storage_removable);
|
||||||
|
|
||||||
SpannableStringBuilder sb = new SpannableStringBuilder();
|
SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||||
sb.append(volumeName + ": \n", new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_3)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
sb.append(volumeName + ": \n", new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_3)),
|
||||||
sb.append("/" + subPath, new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_4)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
sb.append("/" + subPath, new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_4)),
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,12 +68,14 @@ public class BackupUtils
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Integer.parseInt(rawValue);
|
return Integer.parseInt(rawValue);
|
||||||
} catch (NumberFormatException e)
|
}
|
||||||
|
catch (NumberFormatException e)
|
||||||
{
|
{
|
||||||
Logger.e(TAG, "Failed to parse max backups count, raw value: " + rawValue + " set to default: " + MAX_BACKUPS_DEFAULT_COUNT, e);
|
Logger.e(
|
||||||
prefs.edit()
|
TAG,
|
||||||
.putString(MAX_BACKUPS_KEY, String.valueOf(MAX_BACKUPS_DEFAULT_COUNT))
|
"Failed to parse max backups count, raw value: " + rawValue + " set to default: " + MAX_BACKUPS_DEFAULT_COUNT,
|
||||||
.apply();
|
e);
|
||||||
|
prefs.edit().putString(MAX_BACKUPS_KEY, String.valueOf(MAX_BACKUPS_DEFAULT_COUNT)).apply();
|
||||||
return MAX_BACKUPS_DEFAULT_COUNT;
|
return MAX_BACKUPS_DEFAULT_COUNT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,14 @@
|
|||||||
package app.organicmaps.backup;
|
package app.organicmaps.backup;
|
||||||
|
|
||||||
import static app.organicmaps.backup.BackupUtils.getBackupName;
|
|
||||||
import static app.organicmaps.backup.BackupUtils.getBackupFolders;
|
import static app.organicmaps.backup.BackupUtils.getBackupFolders;
|
||||||
|
import static app.organicmaps.backup.BackupUtils.getBackupName;
|
||||||
import static app.organicmaps.sdk.util.StorageUtils.copyFileToDocumentFile;
|
import static app.organicmaps.sdk.util.StorageUtils.copyFileToDocumentFile;
|
||||||
import static app.organicmaps.sdk.util.StorageUtils.deleteDirectoryRecursive;
|
import static app.organicmaps.sdk.util.StorageUtils.deleteDirectoryRecursive;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.documentfile.provider.DocumentFile;
|
import androidx.documentfile.provider.DocumentFile;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult;
|
||||||
@@ -24,6 +16,11 @@ import app.organicmaps.sdk.bookmarks.data.KmlFileType;
|
|||||||
import app.organicmaps.sdk.util.concurrency.ThreadPool;
|
import app.organicmaps.sdk.util.concurrency.ThreadPool;
|
||||||
import app.organicmaps.sdk.util.concurrency.UiThread;
|
import app.organicmaps.sdk.util.concurrency.UiThread;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
import java.io.File;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class LocalBackupManager implements BookmarkManager.BookmarksSharingListener
|
public class LocalBackupManager implements BookmarkManager.BookmarksSharingListener
|
||||||
{
|
{
|
||||||
@@ -65,39 +62,39 @@ public class LocalBackupManager implements BookmarkManager.BookmarksSharingListe
|
|||||||
ErrorCode errorCode = null;
|
ErrorCode errorCode = null;
|
||||||
switch (result.getCode())
|
switch (result.getCode())
|
||||||
{
|
{
|
||||||
case BookmarkSharingResult.SUCCESS ->
|
case BookmarkSharingResult.SUCCESS ->
|
||||||
{
|
{
|
||||||
if (!saveBackup(result))
|
if (!saveBackup(result))
|
||||||
|
{
|
||||||
|
Logger.e(TAG, "Failed to save backup. See system log above");
|
||||||
|
errorCode = ErrorCode.FILE_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.i(TAG, "Backup was created and saved successfully");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case BookmarkSharingResult.EMPTY_CATEGORY ->
|
||||||
|
{
|
||||||
|
errorCode = ErrorCode.EMPTY_CATEGORY;
|
||||||
|
Logger.e(TAG, "Failed to create backup. Category is empty");
|
||||||
|
}
|
||||||
|
case BookmarkSharingResult.ARCHIVE_ERROR ->
|
||||||
|
{
|
||||||
|
errorCode = ErrorCode.ARCHIVE_ERROR;
|
||||||
|
Logger.e(TAG, "Failed to create archive of bookmarks");
|
||||||
|
}
|
||||||
|
case BookmarkSharingResult.FILE_ERROR ->
|
||||||
{
|
{
|
||||||
Logger.e(TAG, "Failed to save backup. See system log above");
|
|
||||||
errorCode = ErrorCode.FILE_ERROR;
|
errorCode = ErrorCode.FILE_ERROR;
|
||||||
|
Logger.e(TAG, "Failed create file for archive");
|
||||||
}
|
}
|
||||||
else
|
default ->
|
||||||
{
|
{
|
||||||
Logger.i(TAG, "Backup was created and saved successfully");
|
errorCode = ErrorCode.UNSUPPORTED;
|
||||||
|
Logger.e(TAG, "Failed to create backup. Unknown error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case BookmarkSharingResult.EMPTY_CATEGORY ->
|
|
||||||
{
|
|
||||||
errorCode = ErrorCode.EMPTY_CATEGORY;
|
|
||||||
Logger.e(TAG, "Failed to create backup. Category is empty");
|
|
||||||
}
|
|
||||||
case BookmarkSharingResult.ARCHIVE_ERROR ->
|
|
||||||
{
|
|
||||||
errorCode = ErrorCode.ARCHIVE_ERROR;
|
|
||||||
Logger.e(TAG, "Failed to create archive of bookmarks");
|
|
||||||
}
|
|
||||||
case BookmarkSharingResult.FILE_ERROR ->
|
|
||||||
{
|
|
||||||
errorCode = ErrorCode.FILE_ERROR;
|
|
||||||
Logger.e(TAG, "Failed create file for archive");
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
errorCode = ErrorCode.UNSUPPORTED;
|
|
||||||
Logger.e(TAG, "Failed to create backup. Unknown error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode finalErrorCode = errorCode;
|
ErrorCode finalErrorCode = errorCode;
|
||||||
UiThread.run(() -> {
|
UiThread.run(() -> {
|
||||||
@@ -139,8 +136,8 @@ public class LocalBackupManager implements BookmarkManager.BookmarksSharingListe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanOldBackups(parentFolder);
|
cleanOldBackups(parentFolder);
|
||||||
|
}
|
||||||
} catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.e(TAG, "Failed to save backup", e);
|
Logger.e(TAG, "Failed to save backup", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import static app.organicmaps.settings.BackupSettingsFragment.LAST_BACKUP_TIME_K
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
|
||||||
public class PeriodicBackupRunner
|
public class PeriodicBackupRunner
|
||||||
@@ -67,7 +65,8 @@ public class PeriodicBackupRunner
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Long.parseLong(prefs.getString(BACKUP_INTERVAL_KEY, defaultValue));
|
return Long.parseLong(prefs.getString(BACKUP_INTERVAL_KEY, defaultValue));
|
||||||
} catch (NumberFormatException e)
|
}
|
||||||
|
catch (NumberFormatException e)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -76,8 +75,7 @@ public class PeriodicBackupRunner
|
|||||||
private void performBackup(String backupFolderPath, int maxBackups)
|
private void performBackup(String backupFolderPath, int maxBackups)
|
||||||
{
|
{
|
||||||
LocalBackupManager backupManager = new LocalBackupManager(activity, backupFolderPath, maxBackups);
|
LocalBackupManager backupManager = new LocalBackupManager(activity, backupFolderPath, maxBackups);
|
||||||
backupManager.setListener(new LocalBackupManager.Listener()
|
backupManager.setListener(new LocalBackupManager.Listener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackupStarted()
|
public void onBackupStarted()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ package app.organicmaps.base;
|
|||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StyleRes;
|
import androidx.annotation.StyleRes;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.util.ThemeUtils;
|
import app.organicmaps.util.ThemeUtils;
|
||||||
|
|
||||||
@@ -38,7 +36,7 @@ public class BaseMwmDialogFragment extends DialogFragment
|
|||||||
int style = getStyle();
|
int style = getStyle();
|
||||||
int theme = getCustomTheme();
|
int theme = getCustomTheme();
|
||||||
if (style != STYLE_NORMAL || theme != 0)
|
if (style != STYLE_NORMAL || theme != 0)
|
||||||
//noinspection WrongConstant
|
// noinspection WrongConstant
|
||||||
setStyle(style, theme);
|
setStyle(style, theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,5 +60,4 @@ public class BaseMwmDialogFragment extends DialogFragment
|
|||||||
throw new IllegalStateException("Before call this method make sure that the context exists");
|
throw new IllegalStateException("Before call this method make sure that the context exists");
|
||||||
return (Application) context.getApplicationContext();
|
return (Application) context.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package app.organicmaps.base;
|
package app.organicmaps.base;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
|
|
||||||
public class BaseMwmFragment extends Fragment implements OnBackPressListener
|
public class BaseMwmFragment extends Fragment implements OnBackPressListener
|
||||||
@@ -20,5 +18,4 @@ public class BaseMwmFragment extends Fragment implements OnBackPressListener
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import android.graphics.Color;
|
|||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import androidx.activity.EdgeToEdge;
|
import androidx.activity.EdgeToEdge;
|
||||||
import androidx.activity.SystemBarStyle;
|
import androidx.activity.SystemBarStyle;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
@@ -18,18 +17,15 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentFactory;
|
import androidx.fragment.app.FragmentFactory;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.SplashActivity;
|
import app.organicmaps.SplashActivity;
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
import app.organicmaps.util.RtlUtils;
|
|
||||||
import app.organicmaps.util.ThemeUtils;
|
|
||||||
import app.organicmaps.sdk.util.concurrency.UiThread;
|
import app.organicmaps.sdk.util.concurrency.UiThread;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
import app.organicmaps.util.RtlUtils;
|
||||||
|
import app.organicmaps.util.ThemeUtils;
|
||||||
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public abstract class BaseMwmFragmentActivity extends AppCompatActivity
|
public abstract class BaseMwmFragmentActivity extends AppCompatActivity
|
||||||
@@ -47,7 +43,7 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
|
|||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
|
|
||||||
if (ThemeUtils.isDefaultTheme(context, theme))
|
if (ThemeUtils.isDefaultTheme(context, theme))
|
||||||
return R.style.MwmTheme;
|
return R.style.MwmTheme;
|
||||||
|
|
||||||
if (ThemeUtils.isNightTheme(context, theme))
|
if (ThemeUtils.isNightTheme(context, theme))
|
||||||
return R.style.MwmTheme_Night;
|
return R.style.MwmTheme_Night;
|
||||||
@@ -216,11 +212,13 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
|
|||||||
/**
|
/**
|
||||||
* Replace attached fragment with the new one.
|
* Replace attached fragment with the new one.
|
||||||
*/
|
*/
|
||||||
public void replaceFragment(@NonNull Class<? extends Fragment> fragmentClass, @Nullable Bundle args, @Nullable Runnable completionListener)
|
public void replaceFragment(@NonNull Class<? extends Fragment> fragmentClass, @Nullable Bundle args,
|
||||||
|
@Nullable Runnable completionListener)
|
||||||
{
|
{
|
||||||
final int resId = getFragmentContentResId();
|
final int resId = getFragmentContentResId();
|
||||||
if (resId <= 0 || findViewById(resId) == null)
|
if (resId <= 0 || findViewById(resId) == null)
|
||||||
throw new IllegalStateException("Fragment can't be added, since getFragmentContentResId() isn't implemented or returns wrong resourceId.");
|
throw new IllegalStateException(
|
||||||
|
"Fragment can't be added, since getFragmentContentResId() isn't implemented or returns wrong resourceId.");
|
||||||
|
|
||||||
String name = fragmentClass.getName();
|
String name = fragmentClass.getName();
|
||||||
Fragment potentialInstance = getSupportFragmentManager().findFragmentByTag(name);
|
Fragment potentialInstance = getSupportFragmentManager().findFragmentByTag(name);
|
||||||
@@ -230,9 +228,7 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
|
|||||||
final FragmentFactory factory = manager.getFragmentFactory();
|
final FragmentFactory factory = manager.getFragmentFactory();
|
||||||
final Fragment fragment = factory.instantiate(getClassLoader(), name);
|
final Fragment fragment = factory.instantiate(getClassLoader(), name);
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
manager.beginTransaction()
|
manager.beginTransaction().replace(resId, fragment, name).commitAllowingStateLoss();
|
||||||
.replace(resId, fragment, name)
|
|
||||||
.commitAllowingStateLoss();
|
|
||||||
manager.executePendingTransactions();
|
manager.executePendingTransactions();
|
||||||
if (completionListener != null)
|
if (completionListener != null)
|
||||||
completionListener.run();
|
completionListener.run();
|
||||||
@@ -240,8 +236,8 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override to automatically attach fragment in onCreate. Tag applied to fragment in back stack is set to fragment name, too.
|
* Override to automatically attach fragment in onCreate. Tag applied to fragment in back stack is set to fragment
|
||||||
* WARNING : if custom layout for activity is set, getFragmentContentResId() must be implemented, too.
|
* name, too. WARNING : if custom layout for activity is set, getFragmentContentResId() must be implemented, too.
|
||||||
* @return class of the fragment, eg FragmentClass.getClass()
|
* @return class of the fragment, eg FragmentClass.getClass()
|
||||||
*/
|
*/
|
||||||
protected Class<? extends Fragment> getFragmentClass()
|
protected Class<? extends Fragment> getFragmentClass()
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import android.os.Bundle;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.LayoutRes;
|
import androidx.annotation.LayoutRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -14,14 +13,12 @@ import androidx.core.view.ViewCompat;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.util.WindowInsetUtils.ScrollableContentInsetsListener;
|
import app.organicmaps.util.WindowInsetUtils.ScrollableContentInsetsListener;
|
||||||
import app.organicmaps.widget.PlaceholderView;
|
import app.organicmaps.widget.PlaceholderView;
|
||||||
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
|
||||||
public abstract class BaseMwmRecyclerFragment<T extends RecyclerView.Adapter> extends Fragment
|
public abstract class BaseMwmRecyclerFragment<T extends RecyclerView.Adapter> extends Fragment
|
||||||
{
|
{
|
||||||
@@ -39,8 +36,7 @@ public abstract class BaseMwmRecyclerFragment<T extends RecyclerView.Adapter> ex
|
|||||||
private T mAdapter;
|
private T mAdapter;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final View.OnClickListener mNavigationClickListener
|
private final View.OnClickListener mNavigationClickListener = view -> Utils.navigateToParent(requireActivity());
|
||||||
= view -> Utils.navigateToParent(requireActivity());
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
protected abstract T createAdapter();
|
protected abstract T createAdapter();
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ package app.organicmaps.base;
|
|||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.organicmaps.widget.ToolbarController;
|
import app.organicmaps.widget.ToolbarController;
|
||||||
|
|
||||||
public class BaseMwmToolbarFragment extends BaseMwmFragment
|
public class BaseMwmToolbarFragment extends BaseMwmFragment
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.base;
|
package app.organicmaps.base;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -10,12 +9,10 @@ import androidx.core.view.ViewCompat;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentFactory;
|
import androidx.fragment.app.FragmentFactory;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
||||||
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
|
||||||
public abstract class BaseToolbarActivity extends BaseMwmFragmentActivity
|
public abstract class BaseToolbarActivity extends BaseMwmFragmentActivity
|
||||||
{
|
{
|
||||||
@@ -73,23 +70,20 @@ public abstract class BaseToolbarActivity extends BaseMwmFragmentActivity
|
|||||||
return R.id.fragment_container;
|
return R.id.fragment_container;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fragment stackFragment(@NonNull Class<? extends Fragment> fragmentClass,
|
public Fragment stackFragment(@NonNull Class<? extends Fragment> fragmentClass, @Nullable String title,
|
||||||
@Nullable String title, @Nullable Bundle args)
|
@Nullable Bundle args)
|
||||||
{
|
{
|
||||||
final int resId = getFragmentContentResId();
|
final int resId = getFragmentContentResId();
|
||||||
if (resId <= 0 || findViewById(resId) == null)
|
if (resId <= 0 || findViewById(resId) == null)
|
||||||
throw new IllegalStateException("Fragment can't be added, since getFragmentContentResId() " +
|
throw new IllegalStateException("Fragment can't be added, since getFragmentContentResId() "
|
||||||
"isn't implemented or returns wrong resourceId.");
|
+ "isn't implemented or returns wrong resourceId.");
|
||||||
|
|
||||||
String name = fragmentClass.getName();
|
String name = fragmentClass.getName();
|
||||||
final FragmentManager manager = getSupportFragmentManager();
|
final FragmentManager manager = getSupportFragmentManager();
|
||||||
final FragmentFactory factory = manager.getFragmentFactory();
|
final FragmentFactory factory = manager.getFragmentFactory();
|
||||||
final Fragment fragment = factory.instantiate(getClassLoader(), name);
|
final Fragment fragment = factory.instantiate(getClassLoader(), name);
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
manager.beginTransaction()
|
manager.beginTransaction().replace(resId, fragment, name).addToBackStack(null).commitAllowingStateLoss();
|
||||||
.replace(resId, fragment, name)
|
|
||||||
.addToBackStack(null)
|
|
||||||
.commitAllowingStateLoss();
|
|
||||||
manager.executePendingTransactions();
|
manager.executePendingTransactions();
|
||||||
|
|
||||||
if (title != null)
|
if (title != null)
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
package app.organicmaps.bookmarks;
|
package app.organicmaps.bookmarks;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class BaseBookmarkCategoryAdapter<V extends RecyclerView.ViewHolder>
|
public abstract class BaseBookmarkCategoryAdapter<V extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<V>
|
||||||
extends RecyclerView.Adapter<V>
|
|
||||||
{
|
{
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -54,6 +50,5 @@ public abstract class BaseBookmarkCategoryAdapter<V extends RecyclerView.ViewHol
|
|||||||
if (position < 0 || position > categories.size() - 1)
|
if (position < 0 || position > categories.size() - 1)
|
||||||
throw new ArrayIndexOutOfBoundsException(position);
|
throw new ArrayIndexOutOfBoundsException(position);
|
||||||
return categories.get(position);
|
return categories.get(position);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,11 @@ package app.organicmaps.bookmarks;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StyleRes;
|
import androidx.annotation.StyleRes;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseToolbarActivity;
|
import app.organicmaps.base.BaseToolbarActivity;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
|
|||||||
@@ -7,16 +7,13 @@ import android.content.Context;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.adapter.OnItemClickListener;
|
import app.organicmaps.adapter.OnItemClickListener;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter<RecyclerView.ViewHolder>
|
public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter<RecyclerView.ViewHolder>
|
||||||
@@ -122,8 +119,7 @@ public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter<Recyc
|
|||||||
case TYPE_ACTION_HEADER ->
|
case TYPE_ACTION_HEADER ->
|
||||||
{
|
{
|
||||||
HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder;
|
HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder;
|
||||||
headerViewHolder.setAction(mMassOperationAction,
|
headerViewHolder.setAction(mMassOperationAction, BookmarkManager.INSTANCE.areAllCategoriesInvisible());
|
||||||
BookmarkManager.INSTANCE.areAllCategoriesInvisible());
|
|
||||||
headerViewHolder.getText().setText(R.string.bookmark_lists);
|
headerViewHolder.getText().setText(R.string.bookmark_lists);
|
||||||
}
|
}
|
||||||
case TYPE_CATEGORY_ITEM ->
|
case TYPE_CATEGORY_ITEM ->
|
||||||
@@ -191,7 +187,6 @@ public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter<Recyc
|
|||||||
|
|
||||||
private int toCategoryPosition(int adapterPosition)
|
private int toCategoryPosition(int adapterPosition)
|
||||||
{
|
{
|
||||||
|
|
||||||
int type = getItemViewType(adapterPosition);
|
int type = getItemViewType(adapterPosition);
|
||||||
if (type != TYPE_CATEGORY_ITEM)
|
if (type != TYPE_CATEGORY_ITEM)
|
||||||
throw new AssertionError("An element at specified position is not category!");
|
throw new AssertionError("An element at specified position is not category!");
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import android.os.Bundle;
|
|||||||
import android.provider.DocumentsContract;
|
import android.provider.DocumentsContract;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
@@ -20,42 +19,35 @@ import androidx.annotation.LayoutRes;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.adapter.OnItemClickListener;
|
import app.organicmaps.adapter.OnItemClickListener;
|
||||||
import app.organicmaps.base.BaseMwmRecyclerFragment;
|
import app.organicmaps.base.BaseMwmRecyclerFragment;
|
||||||
|
import app.organicmaps.dialog.EditTextDialogFragment;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult;
|
||||||
import app.organicmaps.sdk.bookmarks.data.KmlFileType;
|
import app.organicmaps.sdk.bookmarks.data.KmlFileType;
|
||||||
import app.organicmaps.dialog.EditTextDialogFragment;
|
|
||||||
import app.organicmaps.util.SharingUtils;
|
|
||||||
import app.organicmaps.util.Utils;
|
|
||||||
import app.organicmaps.widget.PlaceholderView;
|
|
||||||
import app.organicmaps.widget.recycler.DividerItemDecorationWithPadding;
|
|
||||||
import app.organicmaps.sdk.util.StorageUtils;
|
import app.organicmaps.sdk.util.StorageUtils;
|
||||||
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
|
|
||||||
import app.organicmaps.util.bottomsheet.MenuBottomSheetItem;
|
|
||||||
import app.organicmaps.sdk.util.concurrency.ThreadPool;
|
import app.organicmaps.sdk.util.concurrency.ThreadPool;
|
||||||
import app.organicmaps.sdk.util.concurrency.UiThread;
|
import app.organicmaps.sdk.util.concurrency.UiThread;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
import app.organicmaps.util.SharingUtils;
|
||||||
|
import app.organicmaps.util.Utils;
|
||||||
|
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
|
||||||
|
import app.organicmaps.util.bottomsheet.MenuBottomSheetItem;
|
||||||
|
import app.organicmaps.widget.PlaceholderView;
|
||||||
|
import app.organicmaps.widget.recycler.DividerItemDecorationWithPadding;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<BookmarkCategoriesAdapter>
|
public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<BookmarkCategoriesAdapter>
|
||||||
implements BookmarkManager.BookmarksLoadingListener,
|
implements BookmarkManager.BookmarksLoadingListener, CategoryListCallback, OnItemClickListener<BookmarkCategory>,
|
||||||
CategoryListCallback,
|
OnItemMoreClickListener<BookmarkCategory>, OnItemLongClickListener<BookmarkCategory>,
|
||||||
OnItemClickListener<BookmarkCategory>,
|
BookmarkManager.BookmarksSharingListener, MenuBottomSheetFragment.MenuBottomSheetInterface
|
||||||
OnItemMoreClickListener<BookmarkCategory>,
|
|
||||||
OnItemLongClickListener<BookmarkCategory>,
|
|
||||||
BookmarkManager.BookmarksSharingListener,
|
|
||||||
MenuBottomSheetFragment.MenuBottomSheetInterface
|
|
||||||
|
|
||||||
{
|
{
|
||||||
private static final String TAG = BookmarkCategoriesFragment.class.getSimpleName();
|
private static final String TAG = BookmarkCategoriesFragment.class.getSimpleName();
|
||||||
@@ -75,21 +67,24 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
|
|||||||
@NonNull
|
@NonNull
|
||||||
private DataChangedListener mCategoriesAdapterObserver;
|
private DataChangedListener mCategoriesAdapterObserver;
|
||||||
|
|
||||||
private final ActivityResultLauncher<Intent> startBookmarkListForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
|
private final ActivityResultLauncher<Intent> startBookmarkListForResult =
|
||||||
if( activityResult.getResultCode() == Activity.RESULT_OK)
|
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
|
||||||
onDeleteActionSelected(getSelectedCategory());
|
if (activityResult.getResultCode() == Activity.RESULT_OK)
|
||||||
});
|
onDeleteActionSelected(getSelectedCategory());
|
||||||
|
});
|
||||||
|
|
||||||
private final ActivityResultLauncher<Intent> startImportDirectoryForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult ->
|
private final ActivityResultLauncher<Intent> startImportDirectoryForResult =
|
||||||
{
|
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
|
||||||
if( activityResult.getResultCode() == Activity.RESULT_OK)
|
if (activityResult.getResultCode() == Activity.RESULT_OK)
|
||||||
onImportDirectoryResult(activityResult.getData());
|
onImportDirectoryResult(activityResult.getData());
|
||||||
});
|
});
|
||||||
|
|
||||||
private final ActivityResultLauncher<Intent> startBookmarkSettingsForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
|
|
||||||
// not handled at the moment
|
|
||||||
});
|
|
||||||
|
|
||||||
|
private final ActivityResultLauncher<Intent> startBookmarkSettingsForResult =
|
||||||
|
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
|
||||||
|
activityResult
|
||||||
|
-> {
|
||||||
|
// not handled at the moment
|
||||||
|
});
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@LayoutRes
|
@LayoutRes
|
||||||
@@ -119,7 +114,8 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
|
|||||||
getAdapter().setCategoryListCallback(this);
|
getAdapter().setCategoryListCallback(this);
|
||||||
|
|
||||||
RecyclerView rw = getRecyclerView();
|
RecyclerView rw = getRecyclerView();
|
||||||
if (rw == null) return;
|
if (rw == null)
|
||||||
|
return;
|
||||||
|
|
||||||
rw.setNestedScrollingEnabled(false);
|
rw.setNestedScrollingEnabled(false);
|
||||||
RecyclerView.ItemDecoration decor = new DividerItemDecorationWithPadding(requireContext());
|
RecyclerView.ItemDecoration decor = new DividerItemDecorationWithPadding(requireContext());
|
||||||
@@ -148,7 +144,7 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
|
|||||||
BookmarkManager.INSTANCE.addLoadingListener(this);
|
BookmarkManager.INSTANCE.addLoadingListener(this);
|
||||||
BookmarkManager.INSTANCE.addSharingListener(this);
|
BookmarkManager.INSTANCE.addSharingListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop()
|
public void onStop()
|
||||||
{
|
{
|
||||||
@@ -181,7 +177,7 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
|
|||||||
{
|
{
|
||||||
mSelectedCategory = item;
|
mSelectedCategory = item;
|
||||||
MenuBottomSheetFragment.newInstance(BOOKMARKS_CATEGORIES_MENU_ID, item.getName())
|
MenuBottomSheetFragment.newInstance(BOOKMARKS_CATEGORIES_MENU_ID, item.getName())
|
||||||
.show(getChildFragmentManager(), BOOKMARKS_CATEGORIES_MENU_ID);
|
.show(getChildFragmentManager(), BOOKMARKS_CATEGORIES_MENU_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -191,28 +187,19 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
|
|||||||
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
|
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
|
||||||
if (mSelectedCategory != null)
|
if (mSelectedCategory != null)
|
||||||
{
|
{
|
||||||
items.add(new MenuBottomSheetItem(
|
items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_settings,
|
||||||
R.string.edit,
|
() -> onSettingsActionSelected(mSelectedCategory)));
|
||||||
R.drawable.ic_settings,
|
items.add(new MenuBottomSheetItem(mSelectedCategory.isVisible() ? R.string.hide : R.string.show,
|
||||||
() -> onSettingsActionSelected(mSelectedCategory)));
|
mSelectedCategory.isVisible() ? R.drawable.ic_hide : R.drawable.ic_show,
|
||||||
items.add(new MenuBottomSheetItem(
|
() -> onShowActionSelected(mSelectedCategory)));
|
||||||
mSelectedCategory.isVisible() ? R.string.hide : R.string.show,
|
items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz,
|
||||||
mSelectedCategory.isVisible() ? R.drawable.ic_hide : R.drawable.ic_show,
|
() -> onShareActionSelected(mSelectedCategory, KmlFileType.Text)));
|
||||||
() -> onShowActionSelected(mSelectedCategory)));
|
items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx,
|
||||||
items.add(new MenuBottomSheetItem(
|
() -> onShareActionSelected(mSelectedCategory, KmlFileType.Gpx)));
|
||||||
R.string.export_file,
|
|
||||||
R.drawable.ic_file_kmz,
|
|
||||||
() -> onShareActionSelected(mSelectedCategory, KmlFileType.Text)));
|
|
||||||
items.add(new MenuBottomSheetItem(
|
|
||||||
R.string.export_file_gpx,
|
|
||||||
R.drawable.ic_file_gpx,
|
|
||||||
() -> onShareActionSelected(mSelectedCategory, KmlFileType.Gpx)));
|
|
||||||
// Disallow deleting the last category
|
// Disallow deleting the last category
|
||||||
if (getAdapter().getBookmarkCategories().size() > 1)
|
if (getAdapter().getBookmarkCategories().size() > 1)
|
||||||
items.add(new MenuBottomSheetItem(
|
items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete,
|
||||||
R.string.delete,
|
() -> onDeleteActionSelected(mSelectedCategory)));
|
||||||
R.drawable.ic_delete,
|
|
||||||
() -> onDeleteActionSelected(mSelectedCategory)));
|
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
@@ -245,15 +232,10 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
|
|||||||
{
|
{
|
||||||
mCategoryEditor = BookmarkManager.INSTANCE::createCategory;
|
mCategoryEditor = BookmarkManager.INSTANCE::createCategory;
|
||||||
|
|
||||||
EditTextDialogFragment dialogFragment =
|
EditTextDialogFragment dialogFragment = EditTextDialogFragment.show(
|
||||||
EditTextDialogFragment.show(getString(R.string.bookmarks_create_new_group),
|
getString(R.string.bookmarks_create_new_group), getString(R.string.bookmarks_new_list_hint),
|
||||||
getString(R.string.bookmarks_new_list_hint),
|
getString(R.string.bookmark_set_name), getString(R.string.create), getString(R.string.cancel),
|
||||||
getString(R.string.bookmark_set_name),
|
MAX_CATEGORY_NAME_LENGTH, this, new CategoryValidator());
|
||||||
getString(R.string.create),
|
|
||||||
getString(R.string.cancel),
|
|
||||||
MAX_CATEGORY_NAME_LENGTH,
|
|
||||||
this,
|
|
||||||
new CategoryValidator());
|
|
||||||
dialogFragment.setTextSaveListener(this::onSaveText);
|
dialogFragment.setTextSaveListener(this::onSaveText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +262,8 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
|
|||||||
showNoFileManagerError();
|
showNoFileManagerError();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showNoFileManagerError() {
|
private void showNoFileManagerError()
|
||||||
|
{
|
||||||
new MaterialAlertDialogBuilder(requireActivity())
|
new MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setMessage(R.string.error_no_file_manager_app)
|
.setMessage(R.string.error_no_file_manager_app)
|
||||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss())
|
.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss())
|
||||||
@@ -341,17 +324,16 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
|
|||||||
final ContentResolver resolver = context.getContentResolver();
|
final ContentResolver resolver = context.getContentResolver();
|
||||||
ThreadPool.getStorage().execute(() -> {
|
ThreadPool.getStorage().execute(() -> {
|
||||||
AtomicInteger found = new AtomicInteger(0);
|
AtomicInteger found = new AtomicInteger(0);
|
||||||
StorageUtils.listContentProviderFilesRecursively(
|
StorageUtils.listContentProviderFilesRecursively(resolver, rootUri, uri -> {
|
||||||
resolver, rootUri, uri -> {
|
if (BookmarkManager.INSTANCE.importBookmarksFile(resolver, uri, tempDir))
|
||||||
if (BookmarkManager.INSTANCE.importBookmarksFile(resolver, uri, tempDir))
|
found.incrementAndGet();
|
||||||
found.incrementAndGet();
|
});
|
||||||
});
|
|
||||||
UiThread.run(() -> {
|
UiThread.run(() -> {
|
||||||
if (dialog.isShowing())
|
if (dialog.isShowing())
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
int found_val = found.get();
|
int found_val = found.get();
|
||||||
String message = context.getResources().getQuantityString(
|
String message =
|
||||||
R.plurals.bookmarks_detect_message, found_val, found_val);
|
context.getResources().getQuantityString(R.plurals.bookmarks_detect_message, found_val, found_val);
|
||||||
Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show();
|
Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package app.organicmaps.bookmarks;
|
package app.organicmaps.bookmarks;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmFragmentActivity;
|
import app.organicmaps.base.BaseMwmFragmentActivity;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
@@ -32,11 +30,12 @@ public class BookmarkCategorySettingsActivity extends BaseMwmFragmentActivity
|
|||||||
return BookmarkCategorySettingsFragment.class;
|
return BookmarkCategorySettingsFragment.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startForResult(@NonNull Fragment fragment, ActivityResultLauncher<Intent> startBookmarkSettingsForResult,
|
public static void startForResult(@NonNull Fragment fragment,
|
||||||
@NonNull BookmarkCategory category)
|
ActivityResultLauncher<Intent> startBookmarkSettingsForResult,
|
||||||
|
@NonNull BookmarkCategory category)
|
||||||
{
|
{
|
||||||
android.content.Intent intent = new Intent(fragment.requireActivity(), BookmarkCategorySettingsActivity.class)
|
android.content.Intent intent = new Intent(fragment.requireActivity(), BookmarkCategorySettingsActivity.class)
|
||||||
.putExtra(EXTRA_BOOKMARK_CATEGORY, category);
|
.putExtra(EXTRA_BOOKMARK_CATEGORY, category);
|
||||||
startBookmarkSettingsForResult.launch(intent);
|
startBookmarkSettingsForResult.launch(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,21 +11,17 @@ import android.view.MenuInflater;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmToolbarFragment;
|
import app.organicmaps.base.BaseMwmToolbarFragment;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.util.Utils;
|
|
||||||
|
|
||||||
import app.organicmaps.util.InputUtils;
|
import app.organicmaps.util.InputUtils;
|
||||||
|
import app.organicmaps.util.Utils;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.textfield.TextInputEditText;
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment
|
public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment
|
||||||
@@ -49,14 +45,13 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment
|
|||||||
{
|
{
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
final Bundle args = requireArguments();
|
final Bundle args = requireArguments();
|
||||||
mCategory = Objects.requireNonNull(Utils.getParcelable(args,
|
mCategory = Objects.requireNonNull(
|
||||||
BookmarkCategorySettingsActivity.EXTRA_BOOKMARK_CATEGORY, BookmarkCategory.class));
|
Utils.getParcelable(args, BookmarkCategorySettingsActivity.EXTRA_BOOKMARK_CATEGORY, BookmarkCategory.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
|
||||||
@Nullable Bundle savedInstanceState)
|
|
||||||
{
|
{
|
||||||
View root = inflater.inflate(R.layout.fragment_bookmark_category_settings, container, false);
|
View root = inflater.inflate(R.layout.fragment_bookmark_category_settings, container, false);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
@@ -70,13 +65,13 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment
|
|||||||
TextInputLayout clearNameBtn = root.findViewById(R.id.edit_list_name_input);
|
TextInputLayout clearNameBtn = root.findViewById(R.id.edit_list_name_input);
|
||||||
clearNameBtn.setEndIconOnClickListener(v -> clearAndFocus(mEditCategoryNameView));
|
clearNameBtn.setEndIconOnClickListener(v -> clearAndFocus(mEditCategoryNameView));
|
||||||
mEditCategoryNameView.setText(mCategory.getName());
|
mEditCategoryNameView.setText(mCategory.getName());
|
||||||
InputFilter[] f = { new InputFilter.LengthFilter(TEXT_LENGTH_LIMIT) };
|
InputFilter[] f = {new InputFilter.LengthFilter(TEXT_LENGTH_LIMIT)};
|
||||||
mEditCategoryNameView.setFilters(f);
|
mEditCategoryNameView.setFilters(f);
|
||||||
mEditCategoryNameView.requestFocus();
|
mEditCategoryNameView.requestFocus();
|
||||||
mEditCategoryNameView.addTextChangedListener(new TextWatcher()
|
mEditCategoryNameView.addTextChangedListener(new TextWatcher() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||||
|
{}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||||
@@ -85,7 +80,8 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable editable) {}
|
public void afterTextChanged(Editable editable)
|
||||||
|
{}
|
||||||
});
|
});
|
||||||
mEditDescView = root.findViewById(R.id.edit_description);
|
mEditDescView = root.findViewById(R.id.edit_description);
|
||||||
mEditDescView.setText(mCategory.getDescription());
|
mEditDescView.setText(mCategory.getDescription());
|
||||||
|
|||||||
@@ -3,18 +3,15 @@ package app.organicmaps.bookmarks;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.adapter.OnItemClickListener;
|
import app.organicmaps.adapter.OnItemClickListener;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -22,8 +19,9 @@ import java.util.List;
|
|||||||
public class BookmarkCollectionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
public class BookmarkCollectionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||||
{
|
{
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({ TYPE_HEADER_ITEM, TYPE_CATEGORY_ITEM })
|
@IntDef({TYPE_HEADER_ITEM, TYPE_CATEGORY_ITEM})
|
||||||
public @interface SectionType { }
|
public @interface SectionType
|
||||||
|
{}
|
||||||
|
|
||||||
private final static int TYPE_CATEGORY_ITEM = BookmarkManager.CATEGORY;
|
private final static int TYPE_CATEGORY_ITEM = BookmarkManager.CATEGORY;
|
||||||
private final static int TYPE_HEADER_ITEM = 3;
|
private final static int TYPE_HEADER_ITEM = 3;
|
||||||
@@ -63,11 +61,10 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter<RecyclerView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BookmarkCollectionAdapter(@NonNull BookmarkCategory bookmarkCategory,
|
BookmarkCollectionAdapter(@NonNull BookmarkCategory bookmarkCategory, @NonNull List<BookmarkCategory> itemsCategories)
|
||||||
@NonNull List<BookmarkCategory> itemsCategories)
|
|
||||||
{
|
{
|
||||||
mBookmarkCategory = bookmarkCategory;
|
mBookmarkCategory = bookmarkCategory;
|
||||||
//noinspection AssignmentOrReturnOfFieldWithMutableType
|
// noinspection AssignmentOrReturnOfFieldWithMutableType
|
||||||
mItemsCategory = itemsCategories;
|
mItemsCategory = itemsCategories;
|
||||||
|
|
||||||
mSectionCount = 0;
|
mSectionCount = 0;
|
||||||
@@ -93,7 +90,7 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter<RecyclerView
|
|||||||
@NonNull
|
@NonNull
|
||||||
private List<BookmarkCategory> getItemsListByType(@SectionType int type)
|
private List<BookmarkCategory> getItemsListByType(@SectionType int type)
|
||||||
{
|
{
|
||||||
return mItemsCategory;
|
return mItemsCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -129,18 +126,15 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter<RecyclerView
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, @SectionType int viewType)
|
||||||
@SectionType int viewType)
|
|
||||||
{
|
{
|
||||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||||
RecyclerView.ViewHolder holder = null;
|
RecyclerView.ViewHolder holder = null;
|
||||||
|
|
||||||
if (viewType == TYPE_HEADER_ITEM)
|
if (viewType == TYPE_HEADER_ITEM)
|
||||||
holder = new Holders.HeaderViewHolder(inflater.inflate(R.layout.item_bookmark_group_list_header,
|
holder = new Holders.HeaderViewHolder(inflater.inflate(R.layout.item_bookmark_group_list_header, parent, false));
|
||||||
parent, false));
|
|
||||||
if (viewType == TYPE_CATEGORY_ITEM)
|
if (viewType == TYPE_CATEGORY_ITEM)
|
||||||
holder = new Holders.CollectionViewHolder(inflater.inflate(R.layout.item_bookmark_collection,
|
holder = new Holders.CollectionViewHolder(inflater.inflate(R.layout.item_bookmark_collection, parent, false));
|
||||||
parent, false));
|
|
||||||
|
|
||||||
if (holder == null)
|
if (holder == null)
|
||||||
throw new AssertionError("Unsupported view type: " + viewType);
|
throw new AssertionError("Unsupported view type: " + viewType);
|
||||||
@@ -170,8 +164,7 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter<RecyclerView
|
|||||||
throw new AssertionError("Position not found: " + position);
|
throw new AssertionError("Position not found: " + position);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindCollectionHolder(RecyclerView.ViewHolder holder, SectionPosition position,
|
private void bindCollectionHolder(RecyclerView.ViewHolder holder, SectionPosition position, @SectionType int type)
|
||||||
@SectionType int type)
|
|
||||||
{
|
{
|
||||||
final BookmarkCategory category = getGroupByPosition(position, type);
|
final BookmarkCategory category = getGroupByPosition(position, type);
|
||||||
Holders.CollectionViewHolder collectionViewHolder = (Holders.CollectionViewHolder) holder;
|
Holders.CollectionViewHolder collectionViewHolder = (Holders.CollectionViewHolder) holder;
|
||||||
@@ -188,8 +181,7 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter<RecyclerView
|
|||||||
private void bindHeaderHolder(@NonNull RecyclerView.ViewHolder holder, int nextSectionPosition)
|
private void bindHeaderHolder(@NonNull RecyclerView.ViewHolder holder, int nextSectionPosition)
|
||||||
{
|
{
|
||||||
Holders.HeaderViewHolder headerViewHolder = (Holders.HeaderViewHolder) holder;
|
Holders.HeaderViewHolder headerViewHolder = (Holders.HeaderViewHolder) holder;
|
||||||
headerViewHolder.getText()
|
headerViewHolder.getText().setText(holder.itemView.getResources().getString(R.string.bookmarks));
|
||||||
.setText(holder.itemView.getResources().getString(R.string.bookmarks));
|
|
||||||
final boolean visibility = !BookmarkManager.INSTANCE.areAllCategoriesVisible();
|
final boolean visibility = !BookmarkManager.INSTANCE.areAllCategoriesVisible();
|
||||||
headerViewHolder.setAction(mMassOperationAction, visibility);
|
headerViewHolder.setAction(mMassOperationAction, visibility);
|
||||||
updateVisibility(headerViewHolder.itemView);
|
updateVisibility(headerViewHolder.itemView);
|
||||||
@@ -251,4 +243,3 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter<RecyclerView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,11 @@ package app.organicmaps.bookmarks;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StyleRes;
|
import androidx.annotation.StyleRes;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseToolbarActivity;
|
import app.organicmaps.base.BaseToolbarActivity;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
@@ -58,7 +56,8 @@ public class BookmarkListActivity extends BaseToolbarActivity
|
|||||||
return R.layout.bookmarks_activity;
|
return R.layout.bookmarks_activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void startForResult(@NonNull Fragment fragment, ActivityResultLauncher<Intent> startBookmarkListForResult, @NonNull BookmarkCategory category)
|
static void startForResult(@NonNull Fragment fragment, ActivityResultLauncher<Intent> startBookmarkListForResult,
|
||||||
|
@NonNull BookmarkCategory category)
|
||||||
{
|
{
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
Intent intent = new Intent(fragment.requireActivity(), BookmarkListActivity.class);
|
Intent intent = new Intent(fragment.requireActivity(), BookmarkListActivity.class);
|
||||||
|
|||||||
@@ -4,13 +4,9 @@ import android.content.res.Resources;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkInfo;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkInfo;
|
||||||
@@ -20,7 +16,7 @@ import app.organicmaps.sdk.bookmarks.data.SortedBlock;
|
|||||||
import app.organicmaps.sdk.content.DataSource;
|
import app.organicmaps.sdk.content.DataSource;
|
||||||
import app.organicmaps.widget.recycler.RecyclerClickListener;
|
import app.organicmaps.widget.recycler.RecyclerClickListener;
|
||||||
import app.organicmaps.widget.recycler.RecyclerLongClickListener;
|
import app.organicmaps.widget.recycler.RecyclerLongClickListener;
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -62,12 +58,14 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
mDataSource = dataSource;
|
mDataSource = dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BookmarkCategory getCategory() { return mDataSource.getData(); }
|
public BookmarkCategory getCategory()
|
||||||
|
{
|
||||||
|
return mDataSource.getData();
|
||||||
|
}
|
||||||
|
|
||||||
boolean hasDescription()
|
boolean hasDescription()
|
||||||
{
|
{
|
||||||
return (!mDataSource.getData().getAnnotation().isEmpty() ||
|
return (!mDataSource.getData().getAnnotation().isEmpty() || !mDataSource.getData().getDescription().isEmpty());
|
||||||
!mDataSource.getData().getDescription().isEmpty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidate()
|
void invalidate()
|
||||||
@@ -115,7 +113,10 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionsCount() { return mSectionsCount; }
|
public int getSectionsCount()
|
||||||
|
{
|
||||||
|
return mSectionsCount;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEditable(int sectionIndex)
|
public boolean isEditable(int sectionIndex)
|
||||||
@@ -124,7 +125,10 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTitle(int sectionIndex) { return true; }
|
public boolean hasTitle(int sectionIndex)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getTitle(int sectionIndex, @NonNull Resources rs)
|
public String getTitle(int sectionIndex, @NonNull Resources rs)
|
||||||
@@ -172,15 +176,13 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
@Override
|
@Override
|
||||||
public long getBookmarkId(@NonNull SectionPosition pos)
|
public long getBookmarkId(@NonNull SectionPosition pos)
|
||||||
{
|
{
|
||||||
return BookmarkManager.INSTANCE.getBookmarkIdByPosition(getCategory().getId(),
|
return BookmarkManager.INSTANCE.getBookmarkIdByPosition(getCategory().getId(), pos.getItemIndex());
|
||||||
pos.getItemIndex());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTrackId(@NonNull SectionPosition pos)
|
public long getTrackId(@NonNull SectionPosition pos)
|
||||||
{
|
{
|
||||||
return BookmarkManager.INSTANCE.getTrackIdByPosition(getCategory().getId(),
|
return BookmarkManager.INSTANCE.getTrackIdByPosition(getCategory().getId(), pos.getItemIndex());
|
||||||
pos.getItemIndex());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,30 +191,47 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final List<Long> mSearchResults;
|
private final List<Long> mSearchResults;
|
||||||
|
|
||||||
SearchResultsSectionsDataSource(@NonNull DataSource<BookmarkCategory> dataSource,
|
SearchResultsSectionsDataSource(@NonNull DataSource<BookmarkCategory> dataSource, @NonNull List<Long> searchResults)
|
||||||
@NonNull List<Long> searchResults)
|
|
||||||
{
|
{
|
||||||
super(dataSource);
|
super(dataSource);
|
||||||
mSearchResults = searchResults;
|
mSearchResults = searchResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSectionsCount() { return 1; }
|
public int getSectionsCount()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEditable(int sectionIndex) { return true; }
|
public boolean isEditable(int sectionIndex)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTitle(int sectionIndex) { return false; }
|
public boolean hasTitle(int sectionIndex)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getTitle(int sectionIndex, @NonNull Resources rs) { return null; }
|
public String getTitle(int sectionIndex, @NonNull Resources rs)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemsCount(int sectionIndex) { return mSearchResults.size(); }
|
public int getItemsCount(int sectionIndex)
|
||||||
|
{
|
||||||
|
return mSearchResults.size();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemsType(int sectionIndex) { return TYPE_BOOKMARK; }
|
public int getItemsType(int sectionIndex)
|
||||||
|
{
|
||||||
|
return TYPE_BOOKMARK;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDelete(@NonNull SectionPosition pos)
|
public void onDelete(@NonNull SectionPosition pos)
|
||||||
@@ -238,8 +257,7 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final List<SortedBlock> mSortedBlocks;
|
private final List<SortedBlock> mSortedBlocks;
|
||||||
|
|
||||||
SortedSectionsDataSource(@NonNull DataSource<BookmarkCategory> dataSource,
|
SortedSectionsDataSource(@NonNull DataSource<BookmarkCategory> dataSource, @NonNull List<SortedBlock> sortedBlocks)
|
||||||
@NonNull List<SortedBlock> sortedBlocks)
|
|
||||||
{
|
{
|
||||||
super(dataSource);
|
super(dataSource);
|
||||||
mSortedBlocks = sortedBlocks;
|
mSortedBlocks = sortedBlocks;
|
||||||
@@ -272,7 +290,10 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTitle(int sectionIndex) { return true; }
|
public boolean hasTitle(int sectionIndex)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getTitle(int sectionIndex, @NonNull Resources rs)
|
public String getTitle(int sectionIndex, @NonNull Resources rs)
|
||||||
@@ -423,8 +444,7 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
{
|
{
|
||||||
case TYPE_TRACK:
|
case TYPE_TRACK:
|
||||||
Holders.TrackViewHolder trackHolder =
|
Holders.TrackViewHolder trackHolder =
|
||||||
new Holders.TrackViewHolder(inflater.inflate(R.layout.item_track, parent,
|
new Holders.TrackViewHolder(inflater.inflate(R.layout.item_track, parent, false));
|
||||||
false));
|
|
||||||
trackHolder.setOnClickListener(mClickListener);
|
trackHolder.setOnClickListener(mClickListener);
|
||||||
trackHolder.setOnLongClickListener(mLongClickListener);
|
trackHolder.setOnLongClickListener(mLongClickListener);
|
||||||
trackHolder.setTrackIconClickListener(mIconClickListener);
|
trackHolder.setTrackIconClickListener(mIconClickListener);
|
||||||
@@ -433,8 +453,7 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
|
|||||||
break;
|
break;
|
||||||
case TYPE_BOOKMARK:
|
case TYPE_BOOKMARK:
|
||||||
Holders.BookmarkViewHolder bookmarkHolder =
|
Holders.BookmarkViewHolder bookmarkHolder =
|
||||||
new Holders.BookmarkViewHolder(inflater.inflate(R.layout.item_bookmark, parent,
|
new Holders.BookmarkViewHolder(inflater.inflate(R.layout.item_bookmark, parent, false));
|
||||||
false));
|
|
||||||
bookmarkHolder.setOnClickListener(mClickListener);
|
bookmarkHolder.setOnClickListener(mClickListener);
|
||||||
bookmarkHolder.setOnLongClickListener(mLongClickListener);
|
bookmarkHolder.setOnLongClickListener(mLongClickListener);
|
||||||
holder = bookmarkHolder;
|
holder = bookmarkHolder;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import android.view.MenuInflater;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
@@ -40,9 +39,9 @@ import app.organicmaps.sdk.bookmarks.data.SortedBlock;
|
|||||||
import app.organicmaps.sdk.bookmarks.data.Track;
|
import app.organicmaps.sdk.bookmarks.data.Track;
|
||||||
import app.organicmaps.sdk.search.BookmarkSearchListener;
|
import app.organicmaps.sdk.search.BookmarkSearchListener;
|
||||||
import app.organicmaps.sdk.search.SearchEngine;
|
import app.organicmaps.sdk.search.SearchEngine;
|
||||||
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
import app.organicmaps.util.Graphics;
|
import app.organicmaps.util.Graphics;
|
||||||
import app.organicmaps.util.SharingUtils;
|
import app.organicmaps.util.SharingUtils;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.util.WindowInsetUtils;
|
import app.organicmaps.util.WindowInsetUtils;
|
||||||
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
|
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
|
||||||
@@ -53,16 +52,13 @@ import app.organicmaps.widget.placepage.EditBookmarkFragment;
|
|||||||
import app.organicmaps.widget.recycler.DividerItemDecorationWithPadding;
|
import app.organicmaps.widget.recycler.DividerItemDecorationWithPadding;
|
||||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
|
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
|
||||||
import com.google.android.material.imageview.ShapeableImageView;
|
import com.google.android.material.imageview.ShapeableImageView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter>
|
public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter>
|
||||||
implements BookmarkManager.BookmarksSharingListener,
|
implements BookmarkManager.BookmarksSharingListener, BookmarkManager.BookmarksSortingListener,
|
||||||
BookmarkManager.BookmarksSortingListener,
|
BookmarkManager.BookmarksLoadingListener, BookmarkSearchListener,
|
||||||
BookmarkManager.BookmarksLoadingListener,
|
|
||||||
BookmarkSearchListener,
|
|
||||||
ChooseBookmarksSortingTypeFragment.ChooseSortingTypeListener,
|
ChooseBookmarksSortingTypeFragment.ChooseSortingTypeListener,
|
||||||
MenuBottomSheetFragment.MenuBottomSheetInterface
|
MenuBottomSheetFragment.MenuBottomSheetInterface
|
||||||
{
|
{
|
||||||
@@ -75,15 +71,17 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
private static final String OPTIONS_MENU_ID = "OPTIONS_MENU_BOTTOM_SHEET";
|
private static final String OPTIONS_MENU_ID = "OPTIONS_MENU_BOTTOM_SHEET";
|
||||||
|
|
||||||
private ActivityResultLauncher<SharingUtils.SharingIntent> shareLauncher;
|
private ActivityResultLauncher<SharingUtils.SharingIntent> shareLauncher;
|
||||||
private final ActivityResultLauncher<Intent> startBookmarkListForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
|
private final ActivityResultLauncher<Intent> startBookmarkListForResult =
|
||||||
System.out.println("resultCode: " + activityResult.getResultCode());
|
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
|
||||||
handleActivityResult();
|
System.out.println("resultCode: " + activityResult.getResultCode());
|
||||||
});
|
handleActivityResult();
|
||||||
|
});
|
||||||
|
|
||||||
private final ActivityResultLauncher<Intent> startBookmarkSettingsForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
|
private final ActivityResultLauncher<Intent> startBookmarkSettingsForResult =
|
||||||
System.out.println("resultCode: " + activityResult.getResultCode());
|
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
|
||||||
handleActivityResult();
|
System.out.println("resultCode: " + activityResult.getResultCode());
|
||||||
});
|
handleActivityResult();
|
||||||
|
});
|
||||||
|
|
||||||
@SuppressWarnings("NotNullFieldNotInitialized")
|
@SuppressWarnings("NotNullFieldNotInitialized")
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -104,8 +102,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
private ExtendedFloatingActionButton mFabViewOnMap;
|
private ExtendedFloatingActionButton mFabViewOnMap;
|
||||||
@SuppressWarnings("NotNullFieldNotInitialized")
|
@SuppressWarnings("NotNullFieldNotInitialized")
|
||||||
@NonNull
|
@NonNull
|
||||||
private final RecyclerView.OnScrollListener mRecyclerListener = new RecyclerView.OnScrollListener()
|
private final RecyclerView.OnScrollListener mRecyclerListener = new RecyclerView.OnScrollListener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
|
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
|
||||||
{
|
{
|
||||||
@@ -140,7 +137,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
{
|
{
|
||||||
BookmarkCategory category = mCategoryDataSource.getData();
|
BookmarkCategory category = mCategoryDataSource.getData();
|
||||||
return new ConcatAdapter(initAndGetCollectionAdapter(category.getId()),
|
return new ConcatAdapter(initAndGetCollectionAdapter(category.getId()),
|
||||||
new BookmarkListAdapter(mCategoryDataSource));
|
new BookmarkListAdapter(mCategoryDataSource));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -148,16 +145,15 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
{
|
{
|
||||||
List<BookmarkCategory> mCategoryItems = BookmarkManager.INSTANCE.getChildrenCategories(categoryId);
|
List<BookmarkCategory> mCategoryItems = BookmarkManager.INSTANCE.getChildrenCategories(categoryId);
|
||||||
|
|
||||||
BookmarkCollectionAdapter adapter = new BookmarkCollectionAdapter(getCategoryOrThrow(),
|
BookmarkCollectionAdapter adapter = new BookmarkCollectionAdapter(getCategoryOrThrow(), mCategoryItems);
|
||||||
mCategoryItems);
|
adapter.setOnClickListener(
|
||||||
adapter.setOnClickListener((v, item) -> BookmarkListActivity.startForResult(this, startBookmarkListForResult, item));
|
(v, item) -> BookmarkListActivity.startForResult(this, startBookmarkListForResult, item));
|
||||||
|
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
|
||||||
@Nullable Bundle savedInstanceState)
|
|
||||||
{
|
{
|
||||||
return inflater.inflate(R.layout.fragment_bookmark_list, container, false);
|
return inflater.inflate(R.layout.fragment_bookmark_list, container, false);
|
||||||
}
|
}
|
||||||
@@ -202,8 +198,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
// recycler view already has an InsetListener in BaseMwmRecyclerFragment
|
// recycler view already has an InsetListener in BaseMwmRecyclerFragment
|
||||||
// here we must reset it, because the logic is different from a common use case
|
// here we must reset it, because the logic is different from a common use case
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(
|
ViewCompat.setOnApplyWindowInsetsListener(
|
||||||
getRecyclerView(),
|
getRecyclerView(), new WindowInsetUtils.ScrollableContentInsetsListener(getRecyclerView(), mFabViewOnMap));
|
||||||
new WindowInsetUtils.ScrollableContentInsetsListener(getRecyclerView(), mFabViewOnMap));
|
|
||||||
|
|
||||||
updateLoadingPlaceholder(view, false);
|
updateLoadingPlaceholder(view, false);
|
||||||
}
|
}
|
||||||
@@ -261,8 +256,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
private void configureFab(@NonNull View view)
|
private void configureFab(@NonNull View view)
|
||||||
{
|
{
|
||||||
mFabViewOnMap = view.findViewById(R.id.show_on_map_fab);
|
mFabViewOnMap = view.findViewById(R.id.show_on_map_fab);
|
||||||
mFabViewOnMap.setOnClickListener(v ->
|
mFabViewOnMap.setOnClickListener(v -> {
|
||||||
{
|
|
||||||
final Intent i = makeMwmActivityIntent();
|
final Intent i = makeMwmActivityIntent();
|
||||||
i.putExtra(MwmActivity.EXTRA_CATEGORY_ID, mCategoryDataSource.getData().getId());
|
i.putExtra(MwmActivity.EXTRA_CATEGORY_ID, mCategoryDataSource.getData().getId());
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
@@ -288,13 +282,11 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
{
|
{
|
||||||
if (isEmptySearchResults())
|
if (isEmptySearchResults())
|
||||||
{
|
{
|
||||||
requirePlaceholder().setContent(R.string.search_not_found,
|
requirePlaceholder().setContent(R.string.search_not_found, R.string.search_not_found_query);
|
||||||
R.string.search_not_found_query);
|
|
||||||
}
|
}
|
||||||
else if (isEmpty())
|
else if (isEmpty())
|
||||||
{
|
{
|
||||||
requirePlaceholder().setContent(R.string.bookmarks_empty_list_title,
|
requirePlaceholder().setContent(R.string.bookmarks_empty_list_title, R.string.bookmarks_empty_list_message);
|
||||||
R.string.bookmarks_empty_list_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isEmptyRecycler = isEmpty() || isEmptySearchResults();
|
boolean isEmptyRecycler = isEmpty() || isEmptySearchResults();
|
||||||
@@ -330,9 +322,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
SearchEngine.INSTANCE.cancel();
|
SearchEngine.INSTANCE.cancel();
|
||||||
|
|
||||||
mLastQueryTimestamp = System.nanoTime();
|
mLastQueryTimestamp = System.nanoTime();
|
||||||
if (SearchEngine.INSTANCE.searchInBookmarks(query,
|
if (SearchEngine.INSTANCE.searchInBookmarks(query, mCategoryDataSource.getData().getId(), mLastQueryTimestamp))
|
||||||
mCategoryDataSource.getData().getId(),
|
|
||||||
mLastQueryTimestamp))
|
|
||||||
{
|
{
|
||||||
mToolbarController.showProgress(true);
|
mToolbarController.showProgress(true);
|
||||||
}
|
}
|
||||||
@@ -431,8 +421,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
final double lon = hasMyPosition ? loc.getLongitude() : 0;
|
final double lon = hasMyPosition ? loc.getLongitude() : 0;
|
||||||
|
|
||||||
BookmarkManager.INSTANCE.setLastSortingType(catId, sortingType);
|
BookmarkManager.INSTANCE.setLastSortingType(catId, sortingType);
|
||||||
BookmarkManager.INSTANCE.getSortedCategory(catId, sortingType, hasMyPosition, lat, lon,
|
BookmarkManager.INSTANCE.getSortedCategory(catId, sortingType, hasMyPosition, lat, lon, mLastSortTimestamp);
|
||||||
mLastSortTimestamp);
|
|
||||||
|
|
||||||
updateSortingProgressBar();
|
updateSortingProgressBar();
|
||||||
}
|
}
|
||||||
@@ -446,8 +435,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
@NonNull
|
@NonNull
|
||||||
private BookmarkCollectionAdapter getBookmarkCollectionAdapter()
|
private BookmarkCollectionAdapter getBookmarkCollectionAdapter()
|
||||||
{
|
{
|
||||||
return (BookmarkCollectionAdapter) getAdapter().getAdapters()
|
return (BookmarkCollectionAdapter) getAdapter().getAdapters().get(INDEX_BOOKMARKS_COLLECTION_ADAPTER);
|
||||||
.get(INDEX_BOOKMARKS_COLLECTION_ADAPTER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -525,7 +513,8 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
private int getLastAvailableSortingType()
|
private int getLastAvailableSortingType()
|
||||||
{
|
{
|
||||||
int currentType = getLastSortingType();
|
int currentType = getLastSortingType();
|
||||||
@BookmarkManager.SortingType int[] types = getAvailableSortingTypes();
|
@BookmarkManager.SortingType
|
||||||
|
int[] types = getAvailableSortingTypes();
|
||||||
for (@BookmarkManager.SortingType int type : types)
|
for (@BookmarkManager.SortingType int type : types)
|
||||||
{
|
{
|
||||||
if (type == currentType)
|
if (type == currentType)
|
||||||
@@ -536,14 +525,12 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
|
|
||||||
private boolean isEmpty()
|
private boolean isEmpty()
|
||||||
{
|
{
|
||||||
return !getBookmarkListAdapter().isSearchResults()
|
return !getBookmarkListAdapter().isSearchResults() && getBookmarkListAdapter().getItemCount() == 0;
|
||||||
&& getBookmarkListAdapter().getItemCount() == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEmptySearchResults()
|
private boolean isEmptySearchResults()
|
||||||
{
|
{
|
||||||
return getBookmarkListAdapter().isSearchResults()
|
return getBookmarkListAdapter().isSearchResults() && getBookmarkListAdapter().getItemCount() == 0;
|
||||||
&& getBookmarkListAdapter().getItemCount() == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isLastOwnedCategory()
|
private boolean isLastOwnedCategory()
|
||||||
@@ -589,8 +576,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
i.putExtra(MwmActivity.EXTRA_TRACK_ID, track.getTrackId());
|
i.putExtra(MwmActivity.EXTRA_TRACK_ID, track.getTrackId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onBookmarkClicked(int position, @NonNull Intent i,
|
private void onBookmarkClicked(int position, @NonNull Intent i, @NonNull BookmarkListAdapter adapter)
|
||||||
@NonNull BookmarkListAdapter adapter)
|
|
||||||
{
|
{
|
||||||
final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(position);
|
final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(position);
|
||||||
i.putExtra(MwmActivity.EXTRA_CATEGORY_ID, bookmark.getCategoryId());
|
i.putExtra(MwmActivity.EXTRA_CATEGORY_ID, bookmark.getCategoryId());
|
||||||
@@ -603,7 +589,8 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
|
|
||||||
mSelectedPosition = position;
|
mSelectedPosition = position;
|
||||||
final Track mTrack = (Track) adapter.getItem(mSelectedPosition);
|
final Track mTrack = (Track) adapter.getItem(mSelectedPosition);
|
||||||
if (mTrack == null) return;
|
if (mTrack == null)
|
||||||
|
return;
|
||||||
final Bundle args = new Bundle();
|
final Bundle args = new Bundle();
|
||||||
args.putInt(BookmarkColorDialogFragment.ICON_TYPE, Icon.getColorPosition(mTrack.getColor()));
|
args.putInt(BookmarkColorDialogFragment.ICON_TYPE, Icon.getColorPosition(mTrack.getColor()));
|
||||||
final FragmentManager manager = getChildFragmentManager();
|
final FragmentManager manager = getChildFragmentManager();
|
||||||
@@ -618,9 +605,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
if (from == to)
|
if (from == to)
|
||||||
return;
|
return;
|
||||||
BookmarkManager.INSTANCE.changeTrackColor(mTrack.getTrackId(), to);
|
BookmarkManager.INSTANCE.changeTrackColor(mTrack.getTrackId(), to);
|
||||||
Drawable circle = Graphics.drawCircle(to,
|
Drawable circle = Graphics.drawCircle(to, R.dimen.track_circle_size, requireContext().getResources());
|
||||||
R.dimen.track_circle_size,
|
|
||||||
requireContext().getResources());
|
|
||||||
v.setImageDrawable(circle);
|
v.setImageDrawable(circle);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -644,7 +629,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
case BookmarkListAdapter.TYPE_BOOKMARK:
|
case BookmarkListAdapter.TYPE_BOOKMARK:
|
||||||
final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(mSelectedPosition);
|
final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(mSelectedPosition);
|
||||||
MenuBottomSheetFragment.newInstance(BOOKMARKS_MENU_ID, bookmark.getName())
|
MenuBottomSheetFragment.newInstance(BOOKMARKS_MENU_ID, bookmark.getName())
|
||||||
.show(getChildFragmentManager(), BOOKMARKS_MENU_ID);
|
.show(getChildFragmentManager(), BOOKMARKS_MENU_ID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BookmarkListAdapter.TYPE_TRACK:
|
case BookmarkListAdapter.TYPE_TRACK:
|
||||||
@@ -697,7 +682,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
if (item.getItemId() == R.id.bookmarks_more)
|
if (item.getItemId() == R.id.bookmarks_more)
|
||||||
{
|
{
|
||||||
MenuBottomSheetFragment.newInstance(OPTIONS_MENU_ID, mCategoryDataSource.getData().getName())
|
MenuBottomSheetFragment.newInstance(OPTIONS_MENU_ID, mCategoryDataSource.getData().getName())
|
||||||
.show(getChildFragmentManager(), OPTIONS_MENU_ID);
|
.show(getChildFragmentManager(), OPTIONS_MENU_ID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,29 +699,25 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
{
|
{
|
||||||
BookmarkListAdapter adapter = getBookmarkListAdapter();
|
BookmarkListAdapter adapter = getBookmarkListAdapter();
|
||||||
BookmarkInfo info = (BookmarkInfo) adapter.getItem(mSelectedPosition);
|
BookmarkInfo info = (BookmarkInfo) adapter.getItem(mSelectedPosition);
|
||||||
EditBookmarkFragment.editBookmark(
|
EditBookmarkFragment.editBookmark(info.getCategoryId(), info.getBookmarkId(), requireActivity(),
|
||||||
info.getCategoryId(), info.getBookmarkId(), requireActivity(), getChildFragmentManager(),
|
getChildFragmentManager(), (bookmarkId, movedFromCategory) -> {
|
||||||
(bookmarkId, movedFromCategory) ->
|
if (movedFromCategory)
|
||||||
{
|
resetSearchAndSort();
|
||||||
if (movedFromCategory)
|
else
|
||||||
resetSearchAndSort();
|
adapter.notifyDataSetChanged();
|
||||||
else
|
});
|
||||||
adapter.notifyDataSetChanged();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onTrackEditActionSelected()
|
private void onTrackEditActionSelected()
|
||||||
{
|
{
|
||||||
Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition);
|
Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition);
|
||||||
EditBookmarkFragment.editTrack(
|
EditBookmarkFragment.editTrack(track.getCategoryId(), track.getTrackId(), requireActivity(),
|
||||||
track.getCategoryId(), track.getTrackId(), requireActivity(), getChildFragmentManager(),
|
getChildFragmentManager(), (trackId, movedFromCategory) -> {
|
||||||
(trackId, movedFromCategory) ->
|
if (movedFromCategory)
|
||||||
{
|
resetSearchAndSort();
|
||||||
if (movedFromCategory)
|
else
|
||||||
resetSearchAndSort();
|
getBookmarkListAdapter().notifyDataSetChanged();
|
||||||
else
|
});
|
||||||
getBookmarkListAdapter().notifyDataSetChanged();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDeleteActionSelected()
|
private void onDeleteActionSelected()
|
||||||
@@ -754,8 +735,8 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
|
|
||||||
private void onSortOptionSelected()
|
private void onSortOptionSelected()
|
||||||
{
|
{
|
||||||
ChooseBookmarksSortingTypeFragment.chooseSortingType(getAvailableSortingTypes(),
|
ChooseBookmarksSortingTypeFragment.chooseSortingType(getAvailableSortingTypes(), getLastSortingType(),
|
||||||
getLastSortingType(), requireActivity(), getChildFragmentManager());
|
requireActivity(), getChildFragmentManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onShareOptionSelected(KmlFileType kmlFileType)
|
private void onShareOptionSelected(KmlFileType kmlFileType)
|
||||||
@@ -766,7 +747,8 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
|
|
||||||
private void onSettingsOptionSelected()
|
private void onSettingsOptionSelected()
|
||||||
{
|
{
|
||||||
BookmarkCategorySettingsActivity.startForResult(this, startBookmarkSettingsForResult, mCategoryDataSource.getData());
|
BookmarkCategorySettingsActivity.startForResult(this, startBookmarkSettingsForResult,
|
||||||
|
mCategoryDataSource.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDeleteOptionSelected()
|
private void onDeleteOptionSelected()
|
||||||
@@ -777,14 +759,17 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
|
|
||||||
private ArrayList<MenuBottomSheetItem> getOptionsMenuItems()
|
private ArrayList<MenuBottomSheetItem> getOptionsMenuItems()
|
||||||
{
|
{
|
||||||
@BookmarkManager.SortingType int[] types = getAvailableSortingTypes();
|
@BookmarkManager.SortingType
|
||||||
|
int[] types = getAvailableSortingTypes();
|
||||||
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
|
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
|
||||||
if (!isEmpty())
|
if (!isEmpty())
|
||||||
{
|
{
|
||||||
if (types.length > 0)
|
if (types.length > 0)
|
||||||
items.add(new MenuBottomSheetItem(R.string.sort, R.drawable.ic_sort, this::onSortOptionSelected));
|
items.add(new MenuBottomSheetItem(R.string.sort, R.drawable.ic_sort, this::onSortOptionSelected));
|
||||||
items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz, () -> onShareOptionSelected(KmlFileType.Text)));
|
items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz,
|
||||||
items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx, () -> onShareOptionSelected(KmlFileType.Gpx)));
|
() -> onShareOptionSelected(KmlFileType.Text)));
|
||||||
|
items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx,
|
||||||
|
() -> onShareOptionSelected(KmlFileType.Gpx)));
|
||||||
}
|
}
|
||||||
items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_settings, this::onSettingsOptionSelected));
|
items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_settings, this::onSettingsOptionSelected));
|
||||||
if (!isLastOwnedCategory())
|
if (!isLastOwnedCategory())
|
||||||
@@ -805,9 +790,12 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
{
|
{
|
||||||
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
|
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
|
||||||
items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_edit, this::onTrackEditActionSelected));
|
items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_edit, this::onTrackEditActionSelected));
|
||||||
items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz, () -> onShareTrackSelected(track.getTrackId(), KmlFileType.Text)));
|
items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz,
|
||||||
items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx, () -> onShareTrackSelected(track.getTrackId(), KmlFileType.Gpx)));
|
() -> onShareTrackSelected(track.getTrackId(), KmlFileType.Text)));
|
||||||
items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete, () -> onDeleteTrackSelected(track.getTrackId())));
|
items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx,
|
||||||
|
() -> onShareTrackSelected(track.getTrackId(), KmlFileType.Gpx)));
|
||||||
|
items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete,
|
||||||
|
() -> onDeleteTrackSelected(track.getTrackId())));
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,18 +841,22 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
|
|||||||
@Nullable
|
@Nullable
|
||||||
public ArrayList<MenuBottomSheetItem> getMenuBottomSheetItems(String id)
|
public ArrayList<MenuBottomSheetItem> getMenuBottomSheetItems(String id)
|
||||||
{
|
{
|
||||||
switch (id) {
|
switch (id)
|
||||||
case BOOKMARKS_MENU_ID -> {
|
{
|
||||||
return getBookmarkMenuItems();
|
case BOOKMARKS_MENU_ID ->
|
||||||
}
|
{
|
||||||
case TRACK_MENU_ID -> {
|
return getBookmarkMenuItems();
|
||||||
final Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition);
|
|
||||||
return getTrackMenuItems(track);
|
|
||||||
}
|
|
||||||
case OPTIONS_MENU_ID -> {
|
|
||||||
return getOptionsMenuItems();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
case TRACK_MENU_ID ->
|
||||||
|
{
|
||||||
|
final Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition);
|
||||||
|
return getTrackMenuItems(track);
|
||||||
|
}
|
||||||
|
case OPTIONS_MENU_ID ->
|
||||||
|
{
|
||||||
|
return getOptionsMenuItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,21 @@ package app.organicmaps.bookmarks;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult;
|
||||||
import app.organicmaps.sdk.bookmarks.data.KmlFileType;
|
import app.organicmaps.sdk.bookmarks.data.KmlFileType;
|
||||||
import app.organicmaps.util.SharingUtils;
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
import app.organicmaps.util.SharingUtils;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
public enum BookmarksSharingHelper
|
public enum BookmarksSharingHelper
|
||||||
{
|
{
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
@@ -33,7 +29,7 @@ public enum BookmarksSharingHelper
|
|||||||
public void prepareBookmarkCategoryForSharing(@NonNull Activity context, long catId, KmlFileType kmlFileType)
|
public void prepareBookmarkCategoryForSharing(@NonNull Activity context, long catId, KmlFileType kmlFileType)
|
||||||
{
|
{
|
||||||
showProgressDialog(context);
|
showProgressDialog(context);
|
||||||
BookmarkManager.INSTANCE.prepareCategoriesForSharing(new long[]{catId}, kmlFileType);
|
BookmarkManager.INSTANCE.prepareCategoriesForSharing(new long[] {catId}, kmlFileType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepareTrackForSharing(@NonNull Activity context, long trackId, KmlFileType kmlFileType)
|
public void prepareTrackForSharing(@NonNull Activity context, long trackId, KmlFileType kmlFileType)
|
||||||
@@ -62,13 +58,13 @@ public enum BookmarksSharingHelper
|
|||||||
switch (result.getCode())
|
switch (result.getCode())
|
||||||
{
|
{
|
||||||
case BookmarkSharingResult.SUCCESS ->
|
case BookmarkSharingResult.SUCCESS ->
|
||||||
SharingUtils.shareBookmarkFile(context, launcher, result.getSharingPath(), result.getMimeType());
|
SharingUtils.shareBookmarkFile(context, launcher, result.getSharingPath(), result.getMimeType());
|
||||||
case BookmarkSharingResult.EMPTY_CATEGORY ->
|
case BookmarkSharingResult.EMPTY_CATEGORY ->
|
||||||
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
|
||||||
.setTitle(R.string.bookmarks_error_title_share_empty)
|
.setTitle(R.string.bookmarks_error_title_share_empty)
|
||||||
.setMessage(R.string.bookmarks_error_message_share_empty)
|
.setMessage(R.string.bookmarks_error_message_share_empty)
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show();
|
.show();
|
||||||
case BookmarkSharingResult.ARCHIVE_ERROR, BookmarkSharingResult.FILE_ERROR ->
|
case BookmarkSharingResult.ARCHIVE_ERROR, BookmarkSharingResult.FILE_ERROR ->
|
||||||
{
|
{
|
||||||
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
|
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ package app.organicmaps.bookmarks;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import app.organicmaps.widget.SearchToolbarController;
|
import app.organicmaps.widget.SearchToolbarController;
|
||||||
|
|
||||||
public class BookmarksToolbarController extends SearchToolbarController
|
public class BookmarksToolbarController extends SearchToolbarController
|
||||||
@@ -12,8 +10,7 @@ public class BookmarksToolbarController extends SearchToolbarController
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final BookmarksListFragment mFragment;
|
private final BookmarksListFragment mFragment;
|
||||||
|
|
||||||
BookmarksToolbarController(@NonNull View root, @NonNull Activity activity,
|
BookmarksToolbarController(@NonNull View root, @NonNull Activity activity, @NonNull BookmarksListFragment fragment)
|
||||||
@NonNull BookmarksListFragment fragment)
|
|
||||||
{
|
{
|
||||||
super(root, activity);
|
super(root, activity);
|
||||||
mFragment = fragment;
|
mFragment = fragment;
|
||||||
|
|||||||
@@ -2,13 +2,11 @@ package app.organicmaps.bookmarks;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
|
||||||
import app.organicmaps.dialog.EditTextDialogFragment;
|
import app.organicmaps.dialog.EditTextDialogFragment;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
|
|
||||||
class CategoryValidator implements EditTextDialogFragment.Validator
|
class CategoryValidator implements EditTextDialogFragment.Validator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,19 +4,16 @@ import android.content.Context;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.radiobutton.MaterialRadioButton;
|
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
|
import com.google.android.material.radiobutton.MaterialRadioButton;
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ChooseBookmarkCategoryAdapter extends BaseBookmarkCategoryAdapter<ChooseBookmarkCategoryAdapter.SingleChoiceHolder>
|
public class ChooseBookmarkCategoryAdapter
|
||||||
|
extends BaseBookmarkCategoryAdapter<ChooseBookmarkCategoryAdapter.SingleChoiceHolder>
|
||||||
{
|
{
|
||||||
public static final int VIEW_TYPE_CATEGORY = 0;
|
public static final int VIEW_TYPE_CATEGORY = 0;
|
||||||
public static final int VIEW_TYPE_ADD_NEW = 1;
|
public static final int VIEW_TYPE_ADD_NEW = 1;
|
||||||
@@ -32,8 +29,7 @@ public class ChooseBookmarkCategoryAdapter extends BaseBookmarkCategoryAdapter<C
|
|||||||
|
|
||||||
private CategoryListener mListener;
|
private CategoryListener mListener;
|
||||||
|
|
||||||
public ChooseBookmarkCategoryAdapter(Context context, int pos,
|
public ChooseBookmarkCategoryAdapter(Context context, int pos, @NonNull List<BookmarkCategory> categories)
|
||||||
@NonNull List<BookmarkCategory> categories)
|
|
||||||
{
|
{
|
||||||
super(context, categories);
|
super(context, categories);
|
||||||
mCheckedPosition = pos;
|
mCheckedPosition = pos;
|
||||||
|
|||||||
@@ -5,23 +5,20 @@ import android.os.Bundle;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmDialogFragment;
|
import app.organicmaps.base.BaseMwmDialogFragment;
|
||||||
|
import app.organicmaps.dialog.EditTextDialogFragment;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.dialog.EditTextDialogFragment;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ChooseBookmarkCategoryFragment extends BaseMwmDialogFragment
|
public class ChooseBookmarkCategoryFragment
|
||||||
implements ChooseBookmarkCategoryAdapter.CategoryListener
|
extends BaseMwmDialogFragment implements ChooseBookmarkCategoryAdapter.CategoryListener
|
||||||
{
|
{
|
||||||
public static final String CATEGORY_POSITION = "ExtraCategoryPosition";
|
public static final String CATEGORY_POSITION = "ExtraCategoryPosition";
|
||||||
|
|
||||||
@@ -126,13 +123,8 @@ public class ChooseBookmarkCategoryFragment extends BaseMwmDialogFragment
|
|||||||
@Override
|
@Override
|
||||||
public void onCategoryCreate()
|
public void onCategoryCreate()
|
||||||
{
|
{
|
||||||
EditTextDialogFragment dialogFragment =
|
EditTextDialogFragment dialogFragment = EditTextDialogFragment.show(
|
||||||
EditTextDialogFragment.show(getString(R.string.bookmark_set_name),
|
getString(R.string.bookmark_set_name), null, getString(R.string.ok), null, this, new CategoryValidator());
|
||||||
null,
|
|
||||||
getString(R.string.ok),
|
|
||||||
null,
|
|
||||||
this,
|
|
||||||
new CategoryValidator());
|
|
||||||
dialogFragment.setTextSaveListener(this::createCategory);
|
dialogFragment.setTextSaveListener(this::createCategory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,19 +6,17 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.RadioGroup;
|
import android.widget.RadioGroup;
|
||||||
|
|
||||||
import androidx.annotation.IdRes;
|
import androidx.annotation.IdRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmDialogFragment;
|
import app.organicmaps.base.BaseMwmDialogFragment;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
|
||||||
public class ChooseBookmarksSortingTypeFragment extends BaseMwmDialogFragment
|
public class ChooseBookmarksSortingTypeFragment
|
||||||
implements RadioGroup.OnCheckedChangeListener
|
extends BaseMwmDialogFragment implements RadioGroup.OnCheckedChangeListener
|
||||||
{
|
{
|
||||||
private static final String EXTRA_SORTING_TYPES = "sorting_types";
|
private static final String EXTRA_SORTING_TYPES = "sorting_types";
|
||||||
private static final String EXTRA_CURRENT_SORT_TYPE = "current_sort_type";
|
private static final String EXTRA_CURRENT_SORT_TYPE = "current_sort_type";
|
||||||
@@ -32,17 +30,15 @@ public class ChooseBookmarksSortingTypeFragment extends BaseMwmDialogFragment
|
|||||||
void onSort(@BookmarkManager.SortingType int sortingType);
|
void onSort(@BookmarkManager.SortingType int sortingType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void chooseSortingType(@NonNull @BookmarkManager.SortingType int[] availableTypes,
|
public static void chooseSortingType(@NonNull @BookmarkManager.SortingType int[] availableTypes, int currentType,
|
||||||
int currentType, @NonNull Context context,
|
@NonNull Context context, @NonNull FragmentManager manager)
|
||||||
@NonNull FragmentManager manager)
|
|
||||||
{
|
{
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putIntArray(EXTRA_SORTING_TYPES, availableTypes);
|
args.putIntArray(EXTRA_SORTING_TYPES, availableTypes);
|
||||||
args.putInt(EXTRA_CURRENT_SORT_TYPE, currentType);
|
args.putInt(EXTRA_CURRENT_SORT_TYPE, currentType);
|
||||||
String name = ChooseBookmarksSortingTypeFragment.class.getName();
|
String name = ChooseBookmarksSortingTypeFragment.class.getName();
|
||||||
final ChooseBookmarksSortingTypeFragment fragment = (ChooseBookmarksSortingTypeFragment) manager
|
final ChooseBookmarksSortingTypeFragment fragment =
|
||||||
.getFragmentFactory()
|
(ChooseBookmarksSortingTypeFragment) manager.getFragmentFactory().instantiate(context.getClassLoader(), name);
|
||||||
.instantiate(context.getClassLoader(), name);
|
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
fragment.show(manager, name);
|
fragment.show(manager, name);
|
||||||
}
|
}
|
||||||
@@ -68,14 +64,10 @@ public class ChooseBookmarksSortingTypeFragment extends BaseMwmDialogFragment
|
|||||||
{
|
{
|
||||||
switch (sortingType)
|
switch (sortingType)
|
||||||
{
|
{
|
||||||
case BookmarkManager.SORT_BY_TYPE:
|
case BookmarkManager.SORT_BY_TYPE: return R.id.sort_by_type;
|
||||||
return R.id.sort_by_type;
|
case BookmarkManager.SORT_BY_DISTANCE: return R.id.sort_by_distance;
|
||||||
case BookmarkManager.SORT_BY_DISTANCE:
|
case BookmarkManager.SORT_BY_TIME: return R.id.sort_by_time;
|
||||||
return R.id.sort_by_distance;
|
case BookmarkManager.SORT_BY_NAME: return R.id.sort_by_name;
|
||||||
case BookmarkManager.SORT_BY_TIME:
|
|
||||||
return R.id.sort_by_time;
|
|
||||||
case BookmarkManager.SORT_BY_NAME:
|
|
||||||
return R.id.sort_by_name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return R.id.sort_by_default;
|
return R.id.sort_by_default;
|
||||||
@@ -117,8 +109,7 @@ public class ChooseBookmarksSortingTypeFragment extends BaseMwmDialogFragment
|
|||||||
|
|
||||||
private void onAttachInternal()
|
private void onAttachInternal()
|
||||||
{
|
{
|
||||||
mListener = (ChooseSortingTypeListener) (getParentFragment() == null ? getTargetFragment()
|
mListener = (ChooseSortingTypeListener) (getParentFragment() == null ? getTargetFragment() : getParentFragment());
|
||||||
: getParentFragment());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,16 +6,10 @@ import android.location.Location;
|
|||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.PluralsRes;
|
import androidx.annotation.PluralsRes;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.imageview.ShapeableImageView;
|
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.adapter.OnItemClickListener;
|
import app.organicmaps.adapter.OnItemClickListener;
|
||||||
@@ -24,11 +18,14 @@ import app.organicmaps.sdk.bookmarks.data.BookmarkInfo;
|
|||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.sdk.bookmarks.data.IconClickListener;
|
import app.organicmaps.sdk.bookmarks.data.IconClickListener;
|
||||||
import app.organicmaps.sdk.bookmarks.data.Track;
|
import app.organicmaps.sdk.bookmarks.data.Track;
|
||||||
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
import app.organicmaps.util.Graphics;
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
import app.organicmaps.widget.recycler.RecyclerClickListener;
|
import app.organicmaps.widget.recycler.RecyclerClickListener;
|
||||||
import app.organicmaps.widget.recycler.RecyclerLongClickListener;
|
import app.organicmaps.widget.recycler.RecyclerLongClickListener;
|
||||||
import app.organicmaps.util.Graphics;
|
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import com.google.android.material.imageview.ShapeableImageView;
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
public class Holders
|
public class Holders
|
||||||
{
|
{
|
||||||
@@ -66,7 +63,6 @@ public class Holders
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final MaterialTextView mText;
|
private final MaterialTextView mText;
|
||||||
|
|
||||||
|
|
||||||
HeaderViewHolder(@NonNull View itemView)
|
HeaderViewHolder(@NonNull View itemView)
|
||||||
{
|
{
|
||||||
super(itemView);
|
super(itemView);
|
||||||
@@ -86,23 +82,16 @@ public class Holders
|
|||||||
return mButton;
|
return mButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAction(@NonNull HeaderAction action,
|
void setAction(@NonNull HeaderAction action, final boolean showAll)
|
||||||
final boolean showAll)
|
|
||||||
{
|
{
|
||||||
mButton.setText(showAll
|
mButton.setText(showAll ? R.string.bookmark_lists_show_all : R.string.bookmark_lists_hide_all);
|
||||||
? R.string.bookmark_lists_show_all
|
|
||||||
: R.string.bookmark_lists_hide_all);
|
|
||||||
mButton.setOnClickListener(new ToggleShowAllClickListener(action, showAll));
|
mButton.setOnClickListener(new ToggleShowAllClickListener(action, showAll));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAction(@NonNull HeaderActionChildCategories action,
|
void setAction(@NonNull HeaderActionChildCategories action, final boolean showAll)
|
||||||
final boolean showAll)
|
|
||||||
{
|
{
|
||||||
mButton.setText(showAll
|
mButton.setText(showAll ? R.string.bookmark_lists_show_all : R.string.bookmark_lists_hide_all);
|
||||||
? R.string.bookmark_lists_show_all
|
mButton.setOnClickListener(new ToggleShowAllChildCategoryClickListener(action, showAll));
|
||||||
: R.string.bookmark_lists_hide_all);
|
|
||||||
mButton.setOnClickListener(new ToggleShowAllChildCategoryClickListener(
|
|
||||||
action, showAll));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface HeaderAction
|
public interface HeaderAction
|
||||||
@@ -124,8 +113,7 @@ public class Holders
|
|||||||
private final HeaderActionChildCategories mAction;
|
private final HeaderActionChildCategories mAction;
|
||||||
private final boolean mShowAll;
|
private final boolean mShowAll;
|
||||||
|
|
||||||
ToggleShowAllChildCategoryClickListener(@NonNull HeaderActionChildCategories action,
|
ToggleShowAllChildCategoryClickListener(@NonNull HeaderActionChildCategories action, boolean showAll)
|
||||||
boolean showAll)
|
|
||||||
{
|
{
|
||||||
mAction = action;
|
mAction = action;
|
||||||
mShowAll = showAll;
|
mShowAll = showAll;
|
||||||
@@ -223,7 +211,6 @@ public class Holders
|
|||||||
{
|
{
|
||||||
return resources.getQuantityString(plural, size, size);
|
return resources.getQuantityString(plural, size, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
static class CollectionViewHolder extends CategoryViewHolderBase
|
static class CollectionViewHolder extends CategoryViewHolderBase
|
||||||
{
|
{
|
||||||
@@ -354,17 +341,17 @@ public class Holders
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void bind(@NonNull SectionPosition position,
|
void bind(@NonNull SectionPosition position, @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource)
|
||||||
@NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource)
|
|
||||||
{
|
{
|
||||||
final long bookmarkId = sectionsDataSource.getBookmarkId(position);
|
final long bookmarkId = sectionsDataSource.getBookmarkId(position);
|
||||||
BookmarkInfo bookmark = new BookmarkInfo(sectionsDataSource.getCategory().getId(),
|
BookmarkInfo bookmark = new BookmarkInfo(sectionsDataSource.getCategory().getId(), bookmarkId);
|
||||||
bookmarkId);
|
|
||||||
mName.setText(bookmark.getName());
|
mName.setText(bookmark.getName());
|
||||||
final Location loc = MwmApplication.from(mIcon.getContext()).getLocationHelper().getSavedLocation();
|
final Location loc = MwmApplication.from(mIcon.getContext()).getLocationHelper().getSavedLocation();
|
||||||
|
|
||||||
String distanceValue = loc == null ? "" : bookmark.getDistance(loc.getLatitude(),
|
String distanceValue =
|
||||||
loc.getLongitude(), 0.0).toString(mDistance.getContext());
|
loc == null
|
||||||
|
? ""
|
||||||
|
: bookmark.getDistance(loc.getLatitude(), loc.getLongitude(), 0.0).toString(mDistance.getContext());
|
||||||
String separator = "";
|
String separator = "";
|
||||||
if (!distanceValue.isEmpty() && !bookmark.getFeatureType().isEmpty())
|
if (!distanceValue.isEmpty() && !bookmark.getFeatureType().isEmpty())
|
||||||
separator = " • ";
|
separator = " • ";
|
||||||
@@ -373,11 +360,9 @@ public class Holders
|
|||||||
UiUtils.hideIf(TextUtils.isEmpty(subtitleValue), mDistance);
|
UiUtils.hideIf(TextUtils.isEmpty(subtitleValue), mDistance);
|
||||||
|
|
||||||
mIcon.setImageResource(bookmark.getIcon().getResId());
|
mIcon.setImageResource(bookmark.getIcon().getResId());
|
||||||
Drawable circle = Graphics.drawCircleAndImage(bookmark.getIcon().argb(),
|
Drawable circle =
|
||||||
R.dimen.track_circle_size,
|
Graphics.drawCircleAndImage(bookmark.getIcon().argb(), R.dimen.track_circle_size,
|
||||||
bookmark.getIcon().getResId(),
|
bookmark.getIcon().getResId(), R.dimen.bookmark_icon_size, mIcon.getContext());
|
||||||
R.dimen.bookmark_icon_size,
|
|
||||||
mIcon.getContext());
|
|
||||||
mIcon.setImageDrawable(circle);
|
mIcon.setImageDrawable(circle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -402,19 +387,18 @@ public class Holders
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void bind(@NonNull SectionPosition position,
|
void bind(@NonNull SectionPosition position, @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource)
|
||||||
@NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource)
|
|
||||||
{
|
{
|
||||||
final long trackId = sectionsDataSource.getTrackId(position);
|
final long trackId = sectionsDataSource.getTrackId(position);
|
||||||
Track track = BookmarkManager.INSTANCE.getTrack(trackId);
|
Track track = BookmarkManager.INSTANCE.getTrack(trackId);
|
||||||
mName.setText(track.getName());
|
mName.setText(track.getName());
|
||||||
mDistance.setText(new StringBuilder().append(mDistance.getContext()
|
mDistance.setText(new StringBuilder()
|
||||||
.getString(R.string.length))
|
.append(mDistance.getContext().getString(R.string.length))
|
||||||
.append(" ")
|
.append(" ")
|
||||||
.append(track.getLength().toString(mDistance.getContext()))
|
.append(track.getLength().toString(mDistance.getContext()))
|
||||||
.toString());
|
.toString());
|
||||||
Drawable circle = Graphics.drawCircle(track.getColor(), R.dimen.track_circle_size,
|
Drawable circle =
|
||||||
mIcon.getContext().getResources());
|
Graphics.drawCircle(track.getColor(), R.dimen.track_circle_size, mIcon.getContext().getResources());
|
||||||
mIcon.setImageDrawable(circle);
|
mIcon.setImageDrawable(circle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,8 +425,7 @@ public class Holders
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void bind(@NonNull SectionPosition position,
|
void bind(@NonNull SectionPosition position, @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource)
|
||||||
@NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource)
|
|
||||||
{
|
{
|
||||||
mView.setText(sectionsDataSource.getTitle(position.getSectionIndex(), mView.getResources()));
|
mView.setText(sectionsDataSource.getTitle(position.getSectionIndex(), mView.getResources()));
|
||||||
}
|
}
|
||||||
@@ -465,8 +448,7 @@ public class Holders
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void bind(@NonNull SectionPosition position,
|
void bind(@NonNull SectionPosition position, @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource)
|
||||||
@NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource)
|
|
||||||
{
|
{
|
||||||
mTitle.setText(sectionsDataSource.getCategory().getName());
|
mTitle.setText(sectionsDataSource.getCategory().getName());
|
||||||
bindDescription(sectionsDataSource.getCategory());
|
bindDescription(sectionsDataSource.getCategory());
|
||||||
@@ -474,9 +456,7 @@ public class Holders
|
|||||||
|
|
||||||
private void bindDescription(@NonNull BookmarkCategory category)
|
private void bindDescription(@NonNull BookmarkCategory category)
|
||||||
{
|
{
|
||||||
String desc = TextUtils.isEmpty(category.getAnnotation())
|
String desc = TextUtils.isEmpty(category.getAnnotation()) ? category.getDescription() : category.getAnnotation();
|
||||||
? category.getDescription()
|
|
||||||
: category.getAnnotation();
|
|
||||||
|
|
||||||
String formattedDesc = desc.replace("\n", "<br>");
|
String formattedDesc = desc.replace("\n", "<br>");
|
||||||
Spanned spannedDesc = Utils.fromHtml(formattedDesc);
|
Spanned spannedDesc = Utils.fromHtml(formattedDesc);
|
||||||
|
|||||||
@@ -6,13 +6,10 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
|
|
||||||
import com.google.android.material.imageview.ShapeableImageView;
|
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.Icon;
|
import app.organicmaps.sdk.bookmarks.data.Icon;
|
||||||
import app.organicmaps.util.Graphics;
|
import app.organicmaps.util.Graphics;
|
||||||
|
import com.google.android.material.imageview.ShapeableImageView;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class IconsAdapter extends ArrayAdapter<Icon>
|
public class IconsAdapter extends ArrayAdapter<Icon>
|
||||||
@@ -43,18 +40,13 @@ public class IconsAdapter extends ArrayAdapter<Icon>
|
|||||||
Drawable circle;
|
Drawable circle;
|
||||||
if (icon.getColor() == mCheckedIconColor)
|
if (icon.getColor() == mCheckedIconColor)
|
||||||
{
|
{
|
||||||
circle = Graphics.drawCircleAndImage(getItem(position).argb(),
|
circle = Graphics.drawCircleAndImage(getItem(position).argb(), R.dimen.track_circle_size,
|
||||||
R.dimen.track_circle_size,
|
R.drawable.ic_bookmark_none, R.dimen.bookmark_icon_size, getContext());
|
||||||
R.drawable.ic_bookmark_none,
|
|
||||||
R.dimen.bookmark_icon_size,
|
|
||||||
getContext());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
circle = Graphics.drawCircle(getItem(position).argb(),
|
circle =
|
||||||
R.dimen.select_color_circle_size,
|
Graphics.drawCircle(getItem(position).argb(), R.dimen.select_color_circle_size, getContext().getResources());
|
||||||
getContext().getResources());
|
|
||||||
}
|
}
|
||||||
holder.icon.setImageDrawable(circle);
|
holder.icon.setImageDrawable(circle);
|
||||||
return convertView;
|
return convertView;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.bookmarks;
|
package app.organicmaps.bookmarks;
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
public interface OnItemLongClickListener<T>
|
public interface OnItemLongClickListener<T>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.bookmarks;
|
package app.organicmaps.bookmarks;
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
public interface OnItemMoreClickListener<T>
|
public interface OnItemMoreClickListener<T>
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ package app.organicmaps.bookmarks;
|
|||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.os.ParcelCompat;
|
import androidx.core.os.ParcelCompat;
|
||||||
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.Error;
|
import app.organicmaps.sdk.bookmarks.data.Error;
|
||||||
import app.organicmaps.sdk.bookmarks.data.Result;
|
import app.organicmaps.sdk.bookmarks.data.Result;
|
||||||
|
|
||||||
@@ -28,8 +26,7 @@ public class OperationStatus implements Parcelable
|
|||||||
mError = ParcelCompat.readParcelable(in, Error.class.getClassLoader(), Error.class);
|
mError = ParcelCompat.readParcelable(in, Error.class.getClassLoader(), Error.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<OperationStatus> CREATOR = new Creator<>()
|
public static final Creator<OperationStatus> CREATOR = new Creator<>() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public OperationStatus createFromParcel(Parcel in)
|
public OperationStatus createFromParcel(Parcel in)
|
||||||
{
|
{
|
||||||
@@ -59,9 +56,7 @@ public class OperationStatus implements Parcelable
|
|||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "OperationStatus{" +
|
return "OperationStatus{"
|
||||||
"mResult=" + mResult +
|
+ "mResult=" + mResult + ", mError=" + mError + '}';
|
||||||
", mError=" + mError +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package app.organicmaps.car;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -15,7 +14,6 @@ import androidx.car.app.validation.HostValidator;
|
|||||||
import androidx.core.app.NotificationChannelCompat;
|
import androidx.core.app.NotificationChannelCompat;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
import androidx.core.app.NotificationManagerCompat;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
|
|
||||||
import app.organicmaps.BuildConfig;
|
import app.organicmaps.BuildConfig;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.api.Const;
|
import app.organicmaps.api.Const;
|
||||||
@@ -65,12 +63,13 @@ public final class CarAppService extends androidx.car.app.CarAppService
|
|||||||
return mCarNotificationExtender;
|
return mCarNotificationExtender;
|
||||||
|
|
||||||
final Intent intent = new Intent(Intent.ACTION_VIEW)
|
final Intent intent = new Intent(Intent.ACTION_VIEW)
|
||||||
.setComponent(new ComponentName(context, CarAppService.class))
|
.setComponent(new ComponentName(context, CarAppService.class))
|
||||||
.setData(Uri.fromParts(Const.API_SCHEME, CarAppService.API_CAR_HOST, CarAppService.ACTION_SHOW_NAVIGATION_SCREEN));
|
.setData(Uri.fromParts(Const.API_SCHEME, CarAppService.API_CAR_HOST,
|
||||||
|
CarAppService.ACTION_SHOW_NAVIGATION_SCREEN));
|
||||||
mCarNotificationExtender = new CarAppExtender.Builder()
|
mCarNotificationExtender = new CarAppExtender.Builder()
|
||||||
.setImportance(NotificationManagerCompat.IMPORTANCE_MIN)
|
.setImportance(NotificationManagerCompat.IMPORTANCE_MIN)
|
||||||
.setContentIntent(CarPendingIntent.getCarApp(context, intent.hashCode(), intent, 0))
|
.setContentIntent(CarPendingIntent.getCarApp(context, intent.hashCode(), intent, 0))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return mCarNotificationExtender;
|
return mCarNotificationExtender;
|
||||||
}
|
}
|
||||||
@@ -79,9 +78,10 @@ public final class CarAppService extends androidx.car.app.CarAppService
|
|||||||
{
|
{
|
||||||
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
|
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
|
||||||
final NotificationChannelCompat notificationChannel =
|
final NotificationChannelCompat notificationChannel =
|
||||||
new NotificationChannelCompat.Builder(ANDROID_AUTO_NOTIFICATION_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_MIN)
|
new NotificationChannelCompat
|
||||||
|
.Builder(ANDROID_AUTO_NOTIFICATION_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_MIN)
|
||||||
.setName(getString(R.string.car_notification_channel_name))
|
.setName(getString(R.string.car_notification_channel_name))
|
||||||
.setLightsEnabled(false) // less annoying
|
.setLightsEnabled(false) // less annoying
|
||||||
.setVibrationEnabled(false) // less annoying
|
.setVibrationEnabled(false) // less annoying
|
||||||
.build();
|
.build();
|
||||||
notificationManager.createNotificationChannel(notificationChannel);
|
notificationManager.createNotificationChannel(notificationChannel);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package app.organicmaps.car;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.Screen;
|
import androidx.car.app.Screen;
|
||||||
@@ -11,11 +10,8 @@ import androidx.car.app.Session;
|
|||||||
import androidx.car.app.SessionInfo;
|
import androidx.car.app.SessionInfo;
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.sdk.Framework;
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
|
||||||
import app.organicmaps.car.screens.ErrorScreen;
|
import app.organicmaps.car.screens.ErrorScreen;
|
||||||
import app.organicmaps.car.screens.MapPlaceholderScreen;
|
import app.organicmaps.car.screens.MapPlaceholderScreen;
|
||||||
import app.organicmaps.car.screens.MapScreen;
|
import app.organicmaps.car.screens.MapScreen;
|
||||||
@@ -30,23 +26,24 @@ import app.organicmaps.car.util.CurrentCountryChangedListener;
|
|||||||
import app.organicmaps.car.util.IntentUtils;
|
import app.organicmaps.car.util.IntentUtils;
|
||||||
import app.organicmaps.car.util.ThemeUtils;
|
import app.organicmaps.car.util.ThemeUtils;
|
||||||
import app.organicmaps.car.util.UserActionRequired;
|
import app.organicmaps.car.util.UserActionRequired;
|
||||||
|
import app.organicmaps.routing.RoutingController;
|
||||||
|
import app.organicmaps.sdk.Framework;
|
||||||
|
import app.organicmaps.sdk.PlacePageActivationListener;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||||
import app.organicmaps.sdk.display.DisplayChangedListener;
|
import app.organicmaps.sdk.display.DisplayChangedListener;
|
||||||
import app.organicmaps.sdk.display.DisplayManager;
|
import app.organicmaps.sdk.display.DisplayManager;
|
||||||
import app.organicmaps.sdk.display.DisplayType;
|
import app.organicmaps.sdk.display.DisplayType;
|
||||||
import app.organicmaps.sdk.location.LocationState;
|
import app.organicmaps.sdk.location.LocationState;
|
||||||
import app.organicmaps.routing.RoutingController;
|
|
||||||
import app.organicmaps.sdk.PlacePageActivationListener;
|
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
import app.organicmaps.sdk.util.LocationUtils;
|
import app.organicmaps.sdk.util.LocationUtils;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
import app.organicmaps.sdk.widget.placepage.PlacePageData;
|
import app.organicmaps.sdk.widget.placepage.PlacePageData;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public final class CarAppSession extends Session implements DefaultLifecycleObserver,
|
public final class CarAppSession extends Session implements DefaultLifecycleObserver, LocationState.ModeChangeListener,
|
||||||
LocationState.ModeChangeListener, DisplayChangedListener, PlacePageActivationListener
|
DisplayChangedListener, PlacePageActivationListener
|
||||||
{
|
{
|
||||||
private static final String TAG = CarAppSession.class.getSimpleName();
|
private static final String TAG = CarAppSession.class.getSimpleName();
|
||||||
|
|
||||||
@@ -167,9 +164,12 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse
|
|||||||
MwmApplication.from(getCarContext()).initOrganicMaps(() -> {
|
MwmApplication.from(getCarContext()).initOrganicMaps(() -> {
|
||||||
Config.setFirstStartDialogSeen(getCarContext());
|
Config.setFirstStartDialogSeen(getCarContext());
|
||||||
if (DownloaderHelpers.isWorldMapsDownloadNeeded())
|
if (DownloaderHelpers.isWorldMapsDownloadNeeded())
|
||||||
mScreenManager.push(new DownloadMapsScreenBuilder(getCarContext()).setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.FirstLaunch).build());
|
mScreenManager.push(new DownloadMapsScreenBuilder(getCarContext())
|
||||||
|
.setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.FirstLaunch)
|
||||||
|
.build());
|
||||||
});
|
});
|
||||||
} catch (IOException e)
|
}
|
||||||
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
mInitFailed = true;
|
mInitFailed = true;
|
||||||
Logger.e(TAG, "Failed to initialize the app.");
|
Logger.e(TAG, "Failed to initialize the app.");
|
||||||
@@ -254,7 +254,8 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse
|
|||||||
Framework.nativeDeactivatePopup();
|
Framework.nativeDeactivatePopup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final PlaceScreen placeScreen = new PlaceScreen.Builder(getCarContext(), mSurfaceRenderer).setMapObject(mapObject).build();
|
final PlaceScreen placeScreen =
|
||||||
|
new PlaceScreen.Builder(getCarContext(), mSurfaceRenderer).setMapObject(mapObject).build();
|
||||||
mScreenManager.popToRoot();
|
mScreenManager.popToRoot();
|
||||||
mScreenManager.push(placeScreen);
|
mScreenManager.push(placeScreen);
|
||||||
}
|
}
|
||||||
@@ -282,7 +283,9 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse
|
|||||||
final RoutingController routingController = RoutingController.get();
|
final RoutingController routingController = RoutingController.get();
|
||||||
if (routingController.isPlanning() || routingController.isNavigating() || routingController.hasSavedRoute())
|
if (routingController.isPlanning() || routingController.isNavigating() || routingController.hasSavedRoute())
|
||||||
{
|
{
|
||||||
final PlaceScreen placeScreen = new PlaceScreen.Builder(getCarContext(), mSurfaceRenderer).setMapObject(routingController.getEndPoint()).build();
|
final PlaceScreen placeScreen = new PlaceScreen.Builder(getCarContext(), mSurfaceRenderer)
|
||||||
|
.setMapObject(routingController.getEndPoint())
|
||||||
|
.build();
|
||||||
mScreenManager.popToRoot();
|
mScreenManager.popToRoot();
|
||||||
mScreenManager.push(placeScreen);
|
mScreenManager.push(placeScreen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import static app.organicmaps.sdk.display.DisplayType.Car;
|
|||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.AppManager;
|
import androidx.car.app.AppManager;
|
||||||
@@ -15,11 +14,10 @@ import androidx.car.app.SurfaceContainer;
|
|||||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
import androidx.lifecycle.Lifecycle;
|
import androidx.lifecycle.Lifecycle;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.Framework;
|
import app.organicmaps.sdk.Framework;
|
||||||
import app.organicmaps.sdk.Map;
|
import app.organicmaps.sdk.Map;
|
||||||
import app.organicmaps.sdk.MapRenderingListener;
|
import app.organicmaps.sdk.MapRenderingListener;
|
||||||
import app.organicmaps.R;
|
|
||||||
import app.organicmaps.sdk.display.DisplayManager;
|
import app.organicmaps.sdk.display.DisplayManager;
|
||||||
import app.organicmaps.sdk.settings.UnitLocale;
|
import app.organicmaps.sdk.settings.UnitLocale;
|
||||||
import app.organicmaps.sdk.util.concurrency.UiThread;
|
import app.organicmaps.sdk.util.concurrency.UiThread;
|
||||||
@@ -58,12 +56,9 @@ public class SurfaceRenderer implements DefaultLifecycleObserver, SurfaceCallbac
|
|||||||
mSurface.release();
|
mSurface.release();
|
||||||
mSurface = surfaceContainer.getSurface();
|
mSurface = surfaceContainer.getSurface();
|
||||||
|
|
||||||
mMap.onSurfaceCreated(
|
mMap.onSurfaceCreated(mCarContext, mSurface,
|
||||||
mCarContext,
|
new Rect(0, 0, surfaceContainer.getWidth(), surfaceContainer.getHeight()),
|
||||||
mSurface,
|
surfaceContainer.getDpi());
|
||||||
new Rect(0, 0, surfaceContainer.getWidth(), surfaceContainer.getHeight()),
|
|
||||||
surfaceContainer.getDpi()
|
|
||||||
);
|
|
||||||
mMap.updateBottomWidgetsOffset(mCarContext, -1, -1);
|
mMap.updateBottomWidgetsOffset(mCarContext, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,22 +14,18 @@ import androidx.car.app.model.ItemList;
|
|||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.screens.search.SearchOnMapScreen;
|
import app.organicmaps.car.screens.search.SearchOnMapScreen;
|
||||||
import app.organicmaps.car.util.ThemeUtils;
|
import app.organicmaps.car.util.ThemeUtils;
|
||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CategoriesScreen extends BaseMapScreen
|
public class CategoriesScreen extends BaseMapScreen
|
||||||
{
|
{
|
||||||
private record CategoryData(@StringRes int nameResId, @DrawableRes int iconResId, @DrawableRes int iconNightResId)
|
private record CategoryData(@StringRes int nameResId, @DrawableRes int iconResId, @DrawableRes int iconNightResId) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final List<CategoryData> CATEGORIES = Arrays.asList(
|
private static final List<CategoryData> CATEGORIES = Arrays.asList(
|
||||||
new CategoryData(R.string.category_fuel, R.drawable.ic_category_fuel, R.drawable.ic_category_fuel_night),
|
new CategoryData(R.string.category_fuel, R.drawable.ic_category_fuel, R.drawable.ic_category_fuel_night),
|
||||||
@@ -38,8 +34,7 @@ public class CategoriesScreen extends BaseMapScreen
|
|||||||
new CategoryData(R.string.category_food, R.drawable.ic_category_food, R.drawable.ic_category_food_night),
|
new CategoryData(R.string.category_food, R.drawable.ic_category_food, R.drawable.ic_category_food_night),
|
||||||
new CategoryData(R.string.category_hotel, R.drawable.ic_category_hotel, R.drawable.ic_category_hotel_night),
|
new CategoryData(R.string.category_hotel, R.drawable.ic_category_hotel, R.drawable.ic_category_hotel_night),
|
||||||
new CategoryData(R.string.category_toilet, R.drawable.ic_category_toilet, R.drawable.ic_category_toilet_night),
|
new CategoryData(R.string.category_toilet, R.drawable.ic_category_toilet, R.drawable.ic_category_toilet_night),
|
||||||
new CategoryData(R.string.category_rv, R.drawable.ic_category_rv, R.drawable.ic_category_rv_night)
|
new CategoryData(R.string.category_rv, R.drawable.ic_category_rv, R.drawable.ic_category_rv_night));
|
||||||
);
|
|
||||||
|
|
||||||
private final int MAX_CATEGORIES_SIZE;
|
private final int MAX_CATEGORIES_SIZE;
|
||||||
|
|
||||||
@@ -79,11 +74,15 @@ public class CategoriesScreen extends BaseMapScreen
|
|||||||
{
|
{
|
||||||
final GridItem.Builder itemBuilder = new GridItem.Builder();
|
final GridItem.Builder itemBuilder = new GridItem.Builder();
|
||||||
final String title = getCarContext().getString(CATEGORIES.get(i).nameResId);
|
final String title = getCarContext().getString(CATEGORIES.get(i).nameResId);
|
||||||
@DrawableRes final int iconResId = isNightMode ? CATEGORIES.get(i).iconNightResId : CATEGORIES.get(i).iconResId;
|
@DrawableRes
|
||||||
|
final int iconResId = isNightMode ? CATEGORIES.get(i).iconNightResId : CATEGORIES.get(i).iconResId;
|
||||||
|
|
||||||
itemBuilder.setTitle(title);
|
itemBuilder.setTitle(title);
|
||||||
itemBuilder.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), iconResId)).build());
|
itemBuilder.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), iconResId)).build());
|
||||||
itemBuilder.setOnClickListener(() -> getScreenManager().push(new SearchOnMapScreen.Builder(getCarContext(), getSurfaceRenderer()).setCategory(title).build()));
|
itemBuilder.setOnClickListener(
|
||||||
|
()
|
||||||
|
-> getScreenManager().push(
|
||||||
|
new SearchOnMapScreen.Builder(getCarContext(), getSurfaceRenderer()).setCategory(title).build()));
|
||||||
builder.addItem(itemBuilder.build());
|
builder.addItem(itemBuilder.build());
|
||||||
}
|
}
|
||||||
return new GridTemplate.Builder().setHeader(createHeader()).setSingleList(builder.build()).build();
|
return new GridTemplate.Builder().setHeader(createHeader()).setSingleList(builder.build()).build();
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import androidx.car.app.model.Action;
|
|||||||
import androidx.car.app.model.Header;
|
import androidx.car.app.model.Header;
|
||||||
import androidx.car.app.model.MessageTemplate;
|
import androidx.car.app.model.MessageTemplate;
|
||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.screens.base.BaseScreen;
|
import app.organicmaps.car.screens.base.BaseScreen;
|
||||||
import app.organicmaps.car.util.Colors;
|
import app.organicmaps.car.util.Colors;
|
||||||
@@ -56,17 +55,17 @@ public class ErrorScreen extends BaseScreen implements UserActionRequired
|
|||||||
if (mPositiveButtonText != -1)
|
if (mPositiveButtonText != -1)
|
||||||
{
|
{
|
||||||
builder.addAction(new Action.Builder()
|
builder.addAction(new Action.Builder()
|
||||||
.setBackgroundColor(Colors.BUTTON_ACCEPT)
|
.setBackgroundColor(Colors.BUTTON_ACCEPT)
|
||||||
.setTitle(getCarContext().getString(mPositiveButtonText))
|
.setTitle(getCarContext().getString(mPositiveButtonText))
|
||||||
.setOnClickListener(this::onPositiveButton).build()
|
.setOnClickListener(this::onPositiveButton)
|
||||||
);
|
.build());
|
||||||
}
|
}
|
||||||
if (mNegativeButtonText != -1)
|
if (mNegativeButtonText != -1)
|
||||||
{
|
{
|
||||||
builder.addAction(new Action.Builder()
|
builder.addAction(new Action.Builder()
|
||||||
.setTitle(getCarContext().getString(mNegativeButtonText))
|
.setTitle(getCarContext().getString(mNegativeButtonText))
|
||||||
.setOnClickListener(this::onNegativeButton).build()
|
.setOnClickListener(this::onNegativeButton)
|
||||||
);
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import androidx.car.app.model.CarIcon;
|
|||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.car.app.navigation.model.NavigationTemplate;
|
import androidx.car.app.navigation.model.NavigationTemplate;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
@@ -36,7 +35,8 @@ public class FreeDriveScreen extends BaseMapScreen
|
|||||||
private ActionStrip createActionStrip()
|
private ActionStrip createActionStrip()
|
||||||
{
|
{
|
||||||
final Action.Builder finishActionBuilder = new Action.Builder();
|
final Action.Builder finishActionBuilder = new Action.Builder();
|
||||||
finishActionBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_close)).build());
|
finishActionBuilder.setIcon(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_close)).build());
|
||||||
finishActionBuilder.setOnClickListener(this::finish);
|
finishActionBuilder.setOnClickListener(this::finish);
|
||||||
|
|
||||||
final ActionStrip.Builder builder = new ActionStrip.Builder();
|
final ActionStrip.Builder builder = new ActionStrip.Builder();
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import androidx.car.app.model.Header;
|
|||||||
import androidx.car.app.model.MessageTemplate;
|
import androidx.car.app.model.MessageTemplate;
|
||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.screens.base.BaseScreen;
|
import app.organicmaps.car.screens.base.BaseScreen;
|
||||||
import app.organicmaps.sdk.display.DisplayManager;
|
import app.organicmaps.sdk.display.DisplayManager;
|
||||||
@@ -25,15 +24,19 @@ public class MapPlaceholderScreen extends BaseScreen
|
|||||||
@Override
|
@Override
|
||||||
public Template onGetTemplate()
|
public Template onGetTemplate()
|
||||||
{
|
{
|
||||||
final MessageTemplate.Builder builder = new MessageTemplate.Builder(getCarContext().getString(R.string.car_used_on_the_phone_screen));
|
final MessageTemplate.Builder builder =
|
||||||
|
new MessageTemplate.Builder(getCarContext().getString(R.string.car_used_on_the_phone_screen));
|
||||||
|
|
||||||
final Header.Builder headerBuilder = new Header.Builder();
|
final Header.Builder headerBuilder = new Header.Builder();
|
||||||
headerBuilder.setStartHeaderAction(Action.APP_ICON);
|
headerBuilder.setStartHeaderAction(Action.APP_ICON);
|
||||||
headerBuilder.setTitle(getCarContext().getString(R.string.app_name));
|
headerBuilder.setTitle(getCarContext().getString(R.string.app_name));
|
||||||
builder.setHeader(headerBuilder.build());
|
builder.setHeader(headerBuilder.build());
|
||||||
builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_phone_android)).build());
|
builder.setIcon(
|
||||||
builder.addAction(new Action.Builder().setTitle(getCarContext().getString(R.string.car_continue_in_the_car))
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_phone_android)).build());
|
||||||
.setOnClickListener(() -> DisplayManager.from(getCarContext()).changeDisplay(DisplayType.Car)).build());
|
builder.addAction(new Action.Builder()
|
||||||
|
.setTitle(getCarContext().getString(R.string.car_continue_in_the_car))
|
||||||
|
.setOnClickListener(() -> DisplayManager.from(getCarContext()).changeDisplay(DisplayType.Car))
|
||||||
|
.build());
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import androidx.car.app.model.ItemList;
|
|||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
@@ -56,8 +55,10 @@ public class MapScreen extends BaseMapScreen
|
|||||||
private ActionStrip createActionStrip()
|
private ActionStrip createActionStrip()
|
||||||
{
|
{
|
||||||
final Action.Builder freeDriveScreenBuilder = new Action.Builder();
|
final Action.Builder freeDriveScreenBuilder = new Action.Builder();
|
||||||
freeDriveScreenBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_steering_wheel)).build());
|
freeDriveScreenBuilder.setIcon(
|
||||||
freeDriveScreenBuilder.setOnClickListener(() -> getScreenManager().push(new FreeDriveScreen(getCarContext(), getSurfaceRenderer())));
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_steering_wheel)).build());
|
||||||
|
freeDriveScreenBuilder.setOnClickListener(
|
||||||
|
() -> getScreenManager().push(new FreeDriveScreen(getCarContext(), getSurfaceRenderer())));
|
||||||
|
|
||||||
final ActionStrip.Builder builder = new ActionStrip.Builder();
|
final ActionStrip.Builder builder = new ActionStrip.Builder();
|
||||||
builder.addAction(freeDriveScreenBuilder.build());
|
builder.addAction(freeDriveScreenBuilder.build());
|
||||||
@@ -83,7 +84,8 @@ public class MapScreen extends BaseMapScreen
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Item createSearchItem()
|
private Item createSearchItem()
|
||||||
{
|
{
|
||||||
final CarIcon iconSearch = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build();
|
final CarIcon iconSearch =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build();
|
||||||
|
|
||||||
final GridItem.Builder builder = new GridItem.Builder();
|
final GridItem.Builder builder = new GridItem.Builder();
|
||||||
builder.setTitle(getCarContext().getString(R.string.search));
|
builder.setTitle(getCarContext().getString(R.string.search));
|
||||||
@@ -95,7 +97,8 @@ public class MapScreen extends BaseMapScreen
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Item createCategoriesItem()
|
private Item createCategoriesItem()
|
||||||
{
|
{
|
||||||
final CarIcon iconCategories = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_address)).build();
|
final CarIcon iconCategories =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_address)).build();
|
||||||
|
|
||||||
final GridItem.Builder builder = new GridItem.Builder();
|
final GridItem.Builder builder = new GridItem.Builder();
|
||||||
builder.setImage(iconCategories);
|
builder.setImage(iconCategories);
|
||||||
@@ -107,7 +110,8 @@ public class MapScreen extends BaseMapScreen
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Item createBookmarksItem()
|
private Item createBookmarksItem()
|
||||||
{
|
{
|
||||||
final CarIcon iconBookmarks = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_bookmarks)).build();
|
final CarIcon iconBookmarks =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_bookmarks)).build();
|
||||||
|
|
||||||
final GridItem.Builder builder = new GridItem.Builder();
|
final GridItem.Builder builder = new GridItem.Builder();
|
||||||
builder.setImage(iconBookmarks);
|
builder.setImage(iconBookmarks);
|
||||||
@@ -119,7 +123,8 @@ public class MapScreen extends BaseMapScreen
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Item createSettingsItem()
|
private Item createSettingsItem()
|
||||||
{
|
{
|
||||||
final CarIcon iconSettings = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_settings)).build();
|
final CarIcon iconSettings =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_settings)).build();
|
||||||
|
|
||||||
final GridItem.Builder builder = new GridItem.Builder();
|
final GridItem.Builder builder = new GridItem.Builder();
|
||||||
builder.setImage(iconSettings);
|
builder.setImage(iconSettings);
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ import androidx.car.app.navigation.model.TravelEstimate;
|
|||||||
import androidx.car.app.navigation.model.Trip;
|
import androidx.car.app.navigation.model.Trip;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.sdk.Framework;
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.CarAppService;
|
import app.organicmaps.car.CarAppService;
|
||||||
@@ -29,16 +27,16 @@ import app.organicmaps.car.util.Colors;
|
|||||||
import app.organicmaps.car.util.RoutingUtils;
|
import app.organicmaps.car.util.RoutingUtils;
|
||||||
import app.organicmaps.car.util.ThemeUtils;
|
import app.organicmaps.car.util.ThemeUtils;
|
||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
|
import app.organicmaps.routing.NavigationService;
|
||||||
|
import app.organicmaps.routing.RoutingController;
|
||||||
|
import app.organicmaps.sdk.Framework;
|
||||||
import app.organicmaps.sdk.location.LocationHelper;
|
import app.organicmaps.sdk.location.LocationHelper;
|
||||||
import app.organicmaps.sdk.location.LocationListener;
|
import app.organicmaps.sdk.location.LocationListener;
|
||||||
import app.organicmaps.sdk.routing.JunctionInfo;
|
import app.organicmaps.sdk.routing.JunctionInfo;
|
||||||
import app.organicmaps.routing.NavigationService;
|
|
||||||
import app.organicmaps.routing.RoutingController;
|
|
||||||
import app.organicmaps.sdk.routing.RoutingInfo;
|
import app.organicmaps.sdk.routing.RoutingInfo;
|
||||||
import app.organicmaps.sdk.sound.TtsPlayer;
|
import app.organicmaps.sdk.sound.TtsPlayer;
|
||||||
import app.organicmaps.sdk.util.LocationUtils;
|
import app.organicmaps.sdk.util.LocationUtils;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -75,7 +73,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController
|
|||||||
public Template onGetTemplate()
|
public Template onGetTemplate()
|
||||||
{
|
{
|
||||||
final NavigationTemplate.Builder builder = new NavigationTemplate.Builder();
|
final NavigationTemplate.Builder builder = new NavigationTemplate.Builder();
|
||||||
builder.setBackgroundColor(ThemeUtils.isNightMode(getCarContext()) ? Colors.NAVIGATION_TEMPLATE_BACKGROUND_NIGHT : Colors.NAVIGATION_TEMPLATE_BACKGROUND_DAY);
|
builder.setBackgroundColor(ThemeUtils.isNightMode(getCarContext()) ? Colors.NAVIGATION_TEMPLATE_BACKGROUND_NIGHT
|
||||||
|
: Colors.NAVIGATION_TEMPLATE_BACKGROUND_DAY);
|
||||||
builder.setActionStrip(createActionStrip());
|
builder.setActionStrip(createActionStrip());
|
||||||
builder.setMapActionStrip(UiHelpers.createMapActionStrip(getCarContext(), getSurfaceRenderer()));
|
builder.setMapActionStrip(UiHelpers.createMapActionStrip(getCarContext(), getSurfaceRenderer()));
|
||||||
|
|
||||||
@@ -121,7 +120,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController
|
|||||||
public void onNavigationCancelled()
|
public void onNavigationCancelled()
|
||||||
{
|
{
|
||||||
if (!mNavigationCancelled)
|
if (!mNavigationCancelled)
|
||||||
CarToast.makeText(getCarContext(), getCarContext().getString(R.string.trip_finished), CarToast.LENGTH_LONG).show();
|
CarToast.makeText(getCarContext(), getCarContext().getString(R.string.trip_finished), CarToast.LENGTH_LONG)
|
||||||
|
.show();
|
||||||
finish();
|
finish();
|
||||||
getScreenManager().popToRoot();
|
getScreenManager().popToRoot();
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController
|
|||||||
|
|
||||||
MwmApplication.from(getCarContext()).getLocationHelper().addListener(mLocationListener);
|
MwmApplication.from(getCarContext()).getLocationHelper().addListener(mLocationListener);
|
||||||
if (LocationUtils.checkFineLocationPermission(getCarContext()))
|
if (LocationUtils.checkFineLocationPermission(getCarContext()))
|
||||||
NavigationService.startForegroundService(getCarContext(), CarAppService.getCarNotificationExtender(getCarContext()));
|
NavigationService.startForegroundService(getCarContext(),
|
||||||
|
CarAppService.getCarNotificationExtender(getCarContext()));
|
||||||
updateTrip();
|
updateTrip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +167,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController
|
|||||||
private ActionStrip createActionStrip()
|
private ActionStrip createActionStrip()
|
||||||
{
|
{
|
||||||
final Action.Builder stopActionBuilder = new Action.Builder();
|
final Action.Builder stopActionBuilder = new Action.Builder();
|
||||||
stopActionBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_close)).build());
|
stopActionBuilder.setIcon(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_close)).build());
|
||||||
stopActionBuilder.setOnClickListener(() -> {
|
stopActionBuilder.setOnClickListener(() -> {
|
||||||
mNavigationCancelled = true;
|
mNavigationCancelled = true;
|
||||||
mRoutingController.cancel();
|
mRoutingController.cancel();
|
||||||
@@ -195,7 +197,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController
|
|||||||
@NonNull
|
@NonNull
|
||||||
private NavigationTemplate.NavigationInfo getNavigationInfo()
|
private NavigationTemplate.NavigationInfo getNavigationInfo()
|
||||||
{
|
{
|
||||||
final androidx.car.app.navigation.model.RoutingInfo.Builder builder = new androidx.car.app.navigation.model.RoutingInfo.Builder();
|
final androidx.car.app.navigation.model.RoutingInfo.Builder builder =
|
||||||
|
new androidx.car.app.navigation.model.RoutingInfo.Builder();
|
||||||
|
|
||||||
if (mTrip.isLoading())
|
if (mTrip.isLoading())
|
||||||
{
|
{
|
||||||
@@ -228,7 +231,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController
|
|||||||
private Action createTtsAction()
|
private Action createTtsAction()
|
||||||
{
|
{
|
||||||
final Action.Builder ttsActionBuilder = new Action.Builder();
|
final Action.Builder ttsActionBuilder = new Action.Builder();
|
||||||
@DrawableRes final int imgRes = TtsPlayer.isEnabled() ? R.drawable.ic_voice_on : R.drawable.ic_voice_off;
|
@DrawableRes
|
||||||
|
final int imgRes = TtsPlayer.isEnabled() ? R.drawable.ic_voice_on : R.drawable.ic_voice_off;
|
||||||
ttsActionBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), imgRes)).build());
|
ttsActionBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), imgRes)).build());
|
||||||
ttsActionBuilder.setOnClickListener(() -> {
|
ttsActionBuilder.setOnClickListener(() -> {
|
||||||
TtsPlayer.setEnabled(!TtsPlayer.isEnabled());
|
TtsPlayer.setEnabled(!TtsPlayer.isEnabled());
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import android.content.Intent;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -25,12 +24,8 @@ import androidx.car.app.model.Template;
|
|||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.sdk.Framework;
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.Metadata;
|
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder;
|
import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder;
|
||||||
@@ -41,10 +36,12 @@ import app.organicmaps.car.util.RoutingHelpers;
|
|||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
import app.organicmaps.routing.ResultCodesHelper;
|
import app.organicmaps.routing.ResultCodesHelper;
|
||||||
import app.organicmaps.routing.RoutingController;
|
import app.organicmaps.routing.RoutingController;
|
||||||
import app.organicmaps.sdk.routing.RoutingInfo;
|
import app.organicmaps.sdk.Framework;
|
||||||
import app.organicmaps.sdk.Router;
|
import app.organicmaps.sdk.Router;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.Metadata;
|
||||||
|
import app.organicmaps.sdk.routing.RoutingInfo;
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.Callback, RoutingController.Container
|
public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.Callback, RoutingController.Container
|
||||||
@@ -95,7 +92,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
|
|||||||
mRoutingController.restoreRoute();
|
mRoutingController.restoreRoute();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final boolean hasIncorrectEndPoint = mRoutingController.isPlanning() && (!MapObject.same(mMapObject, mRoutingController.getEndPoint()));
|
final boolean hasIncorrectEndPoint =
|
||||||
|
mRoutingController.isPlanning() && (!MapObject.same(mMapObject, mRoutingController.getEndPoint()));
|
||||||
final boolean hasIncorrectRouterType = mRoutingController.getLastRouterType() != ROUTER;
|
final boolean hasIncorrectRouterType = mRoutingController.getLastRouterType() != ROUTER;
|
||||||
final boolean isNotPlanningMode = !mRoutingController.isPlanning();
|
final boolean isNotPlanningMode = !mRoutingController.isPlanning();
|
||||||
if (hasIncorrectRouterType)
|
if (hasIncorrectRouterType)
|
||||||
@@ -105,7 +103,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
|
|||||||
}
|
}
|
||||||
else if (hasIncorrectEndPoint || isNotPlanningMode)
|
else if (hasIncorrectEndPoint || isNotPlanningMode)
|
||||||
{
|
{
|
||||||
mRoutingController.prepare(MwmApplication.from(getCarContext()).getLocationHelper().getMyPosition(), mMapObject);
|
mRoutingController.prepare(MwmApplication.from(getCarContext()).getLocationHelper().getMyPosition(),
|
||||||
|
mMapObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +158,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
|
|||||||
if (routingInfo != null)
|
if (routingInfo != null)
|
||||||
builder.addRow(getPlaceRouteInfo(routingInfo));
|
builder.addRow(getPlaceRouteInfo(routingInfo));
|
||||||
|
|
||||||
final Row placeOpeningHours = UiHelpers.getPlaceOpeningHoursRow(Objects.requireNonNull(mMapObject), getCarContext());
|
final Row placeOpeningHours =
|
||||||
|
UiHelpers.getPlaceOpeningHoursRow(Objects.requireNonNull(mMapObject), getCarContext());
|
||||||
if (placeOpeningHours != null)
|
if (placeOpeningHours != null)
|
||||||
builder.addRow(placeOpeningHours);
|
builder.addRow(placeOpeningHours);
|
||||||
|
|
||||||
@@ -195,7 +195,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
|
|||||||
builder.setTitle(time);
|
builder.setTitle(time);
|
||||||
|
|
||||||
final SpannableString distance = new SpannableString(" ");
|
final SpannableString distance = new SpannableString(" ");
|
||||||
distance.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(routingInfo.distToTarget)), 0, 1, SPAN_INCLUSIVE_INCLUSIVE);
|
distance.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(routingInfo.distToTarget)), 0, 1,
|
||||||
|
SPAN_INCLUSIVE_INCLUSIVE);
|
||||||
distance.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, SPAN_EXCLUSIVE_EXCLUSIVE);
|
distance.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
builder.addText(distance);
|
builder.addText(distance);
|
||||||
|
|
||||||
@@ -211,8 +212,10 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
|
|||||||
{
|
{
|
||||||
final String phoneNumber = phones.split(";", 1)[0];
|
final String phoneNumber = phones.split(";", 1)[0];
|
||||||
final Action.Builder openDialBuilder = new Action.Builder();
|
final Action.Builder openDialBuilder = new Action.Builder();
|
||||||
openDialBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_phone)).build());
|
openDialBuilder.setIcon(
|
||||||
openDialBuilder.setOnClickListener(() -> getCarContext().startCarApp(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber))));
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_phone)).build());
|
||||||
|
openDialBuilder.setOnClickListener(
|
||||||
|
() -> getCarContext().startCarApp(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber))));
|
||||||
builder.addAction(openDialBuilder.build());
|
builder.addAction(openDialBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +227,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
|
|||||||
startRouteBuilder.setBackgroundColor(Colors.START_NAVIGATION);
|
startRouteBuilder.setBackgroundColor(Colors.START_NAVIGATION);
|
||||||
startRouteBuilder.setFlags(Action.FLAG_DEFAULT);
|
startRouteBuilder.setFlags(Action.FLAG_DEFAULT);
|
||||||
startRouteBuilder.setTitle(getCarContext().getString(R.string.p2p_start));
|
startRouteBuilder.setTitle(getCarContext().getString(R.string.p2p_start));
|
||||||
startRouteBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_follow_and_rotate)).build());
|
startRouteBuilder.setIcon(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_follow_and_rotate)).build());
|
||||||
startRouteBuilder.setOnClickListener(() -> {
|
startRouteBuilder.setOnClickListener(() -> {
|
||||||
Config.acceptRoutingDisclaimer();
|
Config.acceptRoutingDisclaimer();
|
||||||
mRoutingController.start();
|
mRoutingController.start();
|
||||||
@@ -238,7 +242,10 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
|
|||||||
{
|
{
|
||||||
return new Action.Builder()
|
return new Action.Builder()
|
||||||
.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_settings)).build())
|
.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_settings)).build())
|
||||||
.setOnClickListener(() -> getScreenManager().pushForResult(new DrivingOptionsScreen(getCarContext(), getSurfaceRenderer()), this::onDrivingOptionsResult))
|
.setOnClickListener(
|
||||||
|
()
|
||||||
|
-> getScreenManager().pushForResult(new DrivingOptionsScreen(getCarContext(), getSurfaceRenderer()),
|
||||||
|
this::onDrivingOptionsResult))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,8 +317,7 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
|
|||||||
else
|
else
|
||||||
mRoutingController.checkAndBuildRoute();
|
mRoutingController.checkAndBuildRoute();
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CarToast.makeText(getCarContext(), R.string.unable_to_calc_alert_title, CarToast.LENGTH_LONG).show();
|
CarToast.makeText(getCarContext(), R.string.unable_to_calc_alert_title, CarToast.LENGTH_LONG).show();
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package app.organicmaps.car.screens.base;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
|
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
|
|
||||||
public abstract class BaseMapScreen extends BaseScreen
|
public abstract class BaseMapScreen extends BaseScreen
|
||||||
|
|||||||
@@ -10,14 +10,12 @@ import androidx.car.app.model.ListTemplate;
|
|||||||
import androidx.car.app.model.Row;
|
import androidx.car.app.model.Row;
|
||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -65,7 +63,8 @@ public class BookmarkCategoriesScreen extends BaseMapScreen
|
|||||||
Row.Builder itemBuilder = new Row.Builder();
|
Row.Builder itemBuilder = new Row.Builder();
|
||||||
itemBuilder.setTitle(bookmarkCategory.getName());
|
itemBuilder.setTitle(bookmarkCategory.getName());
|
||||||
itemBuilder.addText(bookmarkCategory.getDescription());
|
itemBuilder.addText(bookmarkCategory.getDescription());
|
||||||
itemBuilder.setOnClickListener(() -> getScreenManager().push(new BookmarksScreen(getCarContext(), getSurfaceRenderer(), bookmarkCategory)));
|
itemBuilder.setOnClickListener(
|
||||||
|
() -> getScreenManager().push(new BookmarksScreen(getCarContext(), getSurfaceRenderer(), bookmarkCategory)));
|
||||||
itemBuilder.setBrowsable(true);
|
itemBuilder.setBrowsable(true);
|
||||||
builder.addItem(itemBuilder.build());
|
builder.addItem(itemBuilder.build());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -15,21 +14,19 @@ import androidx.car.app.model.ForegroundCarColorSpan;
|
|||||||
import androidx.car.app.model.ItemList;
|
import androidx.car.app.model.ItemList;
|
||||||
import androidx.car.app.model.Row;
|
import androidx.car.app.model.Row;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
|
import app.organicmaps.car.util.Colors;
|
||||||
|
import app.organicmaps.car.util.RoutingHelpers;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkInfo;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkInfo;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import app.organicmaps.sdk.bookmarks.data.Icon;
|
import app.organicmaps.sdk.bookmarks.data.Icon;
|
||||||
import app.organicmaps.sdk.bookmarks.data.SortedBlock;
|
import app.organicmaps.sdk.bookmarks.data.SortedBlock;
|
||||||
import app.organicmaps.car.util.Colors;
|
|
||||||
import app.organicmaps.car.util.RoutingHelpers;
|
|
||||||
import app.organicmaps.sdk.util.Distance;
|
import app.organicmaps.sdk.util.Distance;
|
||||||
import app.organicmaps.util.Graphics;
|
|
||||||
import app.organicmaps.sdk.util.concurrency.ThreadPool;
|
import app.organicmaps.sdk.util.concurrency.ThreadPool;
|
||||||
import app.organicmaps.sdk.util.concurrency.UiThread;
|
import app.organicmaps.sdk.util.concurrency.UiThread;
|
||||||
|
import app.organicmaps.util.Graphics;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -63,7 +60,8 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener
|
|||||||
private final long mBookmarkCategoryId;
|
private final long mBookmarkCategoryId;
|
||||||
private final int mBookmarksListSize;
|
private final int mBookmarksListSize;
|
||||||
|
|
||||||
public BookmarksLoader(@NonNull CarContext carContext, @NonNull BookmarkCategory bookmarkCategory, @NonNull OnBookmarksLoaded onBookmarksLoaded)
|
public BookmarksLoader(@NonNull CarContext carContext, @NonNull BookmarkCategory bookmarkCategory,
|
||||||
|
@NonNull OnBookmarksLoaded onBookmarksLoaded)
|
||||||
{
|
{
|
||||||
final ConstraintManager constraintManager = carContext.getCarService(ConstraintManager.class);
|
final ConstraintManager constraintManager = carContext.getCarService(ConstraintManager.class);
|
||||||
final int maxCategoriesSize = constraintManager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_LIST);
|
final int maxCategoriesSize = constraintManager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_LIST);
|
||||||
@@ -71,7 +69,8 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener
|
|||||||
mCarContext = carContext;
|
mCarContext = carContext;
|
||||||
mOnBookmarksLoaded = onBookmarksLoaded;
|
mOnBookmarksLoaded = onBookmarksLoaded;
|
||||||
mBookmarkCategoryId = bookmarkCategory.getId();
|
mBookmarkCategoryId = bookmarkCategory.getId();
|
||||||
mBookmarksListSize = Math.min(bookmarkCategory.getBookmarksCount(), Math.min(maxCategoriesSize, MAX_BOOKMARKS_SIZE));
|
mBookmarksListSize =
|
||||||
|
Math.min(bookmarkCategory.getBookmarksCount(), Math.min(maxCategoriesSize, MAX_BOOKMARKS_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load()
|
public void load()
|
||||||
@@ -161,12 +160,10 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener
|
|||||||
final Icon icon = bookmarkInfo.getIcon();
|
final Icon icon = bookmarkInfo.getIcon();
|
||||||
if (!iconsCache.containsKey(icon))
|
if (!iconsCache.containsKey(icon))
|
||||||
{
|
{
|
||||||
final Drawable drawable = Graphics.drawCircleAndImage(icon.argb(),
|
final Drawable drawable = Graphics.drawCircleAndImage(icon.argb(), R.dimen.track_circle_size, icon.getResId(),
|
||||||
R.dimen.track_circle_size,
|
R.dimen.bookmark_icon_size, mCarContext);
|
||||||
icon.getResId(),
|
final CarIcon carIcon =
|
||||||
R.dimen.bookmark_icon_size,
|
new CarIcon.Builder(IconCompat.createWithBitmap(Graphics.drawableToBitmap(drawable))).build();
|
||||||
mCarContext);
|
|
||||||
final CarIcon carIcon = new CarIcon.Builder(IconCompat.createWithBitmap(Graphics.drawableToBitmap(drawable))).build();
|
|
||||||
iconsCache.put(icon, carIcon);
|
iconsCache.put(icon, carIcon);
|
||||||
}
|
}
|
||||||
itemBuilder.setImage(Objects.requireNonNull(iconsCache.get(icon)));
|
itemBuilder.setImage(Objects.requireNonNull(iconsCache.get(icon)));
|
||||||
@@ -184,7 +181,8 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener
|
|||||||
{
|
{
|
||||||
result.append(" ");
|
result.append(" ");
|
||||||
final Distance distance = bookmark.getDistance(location.getLatitude(), location.getLongitude(), 0.0);
|
final Distance distance = bookmark.getDistance(location.getLatitude(), location.getLongitude(), 0.0);
|
||||||
result.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(distance)), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
result.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(distance)), 0, 1,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
result.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
result.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,11 @@ import androidx.car.app.model.Template;
|
|||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
|
|
||||||
public class BookmarksScreen extends BaseMapScreen
|
public class BookmarksScreen extends BaseMapScreen
|
||||||
{
|
{
|
||||||
@@ -32,7 +31,8 @@ public class BookmarksScreen extends BaseMapScreen
|
|||||||
|
|
||||||
private boolean mIsOnSortingScreen = false;
|
private boolean mIsOnSortingScreen = false;
|
||||||
|
|
||||||
public BookmarksScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, @NonNull BookmarkCategory bookmarkCategory)
|
public BookmarksScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer,
|
||||||
|
@NonNull BookmarkCategory bookmarkCategory)
|
||||||
{
|
{
|
||||||
super(carContext, surfaceRenderer);
|
super(carContext, surfaceRenderer);
|
||||||
mBookmarkCategory = bookmarkCategory;
|
mBookmarkCategory = bookmarkCategory;
|
||||||
@@ -90,7 +90,8 @@ public class BookmarksScreen extends BaseMapScreen
|
|||||||
builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_sort)).build());
|
builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_sort)).build());
|
||||||
builder.setOnClickListener(() -> {
|
builder.setOnClickListener(() -> {
|
||||||
mIsOnSortingScreen = true;
|
mIsOnSortingScreen = true;
|
||||||
getScreenManager().pushForResult(new SortingScreen(getCarContext(), getSurfaceRenderer(), mBookmarkCategory), this::onSortingResult);
|
getScreenManager().pushForResult(new SortingScreen(getCarContext(), getSurfaceRenderer(), mBookmarkCategory),
|
||||||
|
this::onSortingResult);
|
||||||
});
|
});
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.car.screens.bookmarks;
|
package app.organicmaps.car.screens.bookmarks;
|
||||||
|
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -15,15 +14,13 @@ import androidx.car.app.model.Template;
|
|||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.BookmarkCategory;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
@@ -41,11 +38,14 @@ class SortingScreen extends BaseMapScreen
|
|||||||
|
|
||||||
private @BookmarkManager.SortingType int mNewSortingType;
|
private @BookmarkManager.SortingType int mNewSortingType;
|
||||||
|
|
||||||
public SortingScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, @NonNull BookmarkCategory bookmarkCategory)
|
public SortingScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer,
|
||||||
|
@NonNull BookmarkCategory bookmarkCategory)
|
||||||
{
|
{
|
||||||
super(carContext, surfaceRenderer);
|
super(carContext, surfaceRenderer);
|
||||||
mRadioButtonIcon = new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_unchecked)).build();
|
mRadioButtonIcon =
|
||||||
mRadioButtonSelectedIcon = new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_checked)).build();
|
new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_unchecked)).build();
|
||||||
|
mRadioButtonSelectedIcon =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_checked)).build();
|
||||||
|
|
||||||
mBookmarkCategoryId = bookmarkCategory.getId();
|
mBookmarkCategoryId = bookmarkCategory.getId();
|
||||||
mLastSortingType = mNewSortingType = getLastSortingType();
|
mLastSortingType = mNewSortingType = getLastSortingType();
|
||||||
@@ -90,10 +90,12 @@ class SortingScreen extends BaseMapScreen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private ItemList createSortingTypesList(@NonNull final @BookmarkManager.SortingType int[] availableSortingTypes, final int lastSortingType)
|
private ItemList createSortingTypesList(@NonNull final @BookmarkManager.SortingType int[] availableSortingTypes,
|
||||||
|
final int lastSortingType)
|
||||||
{
|
{
|
||||||
final ItemList.Builder builder = new ItemList.Builder();
|
final ItemList.Builder builder = new ItemList.Builder();
|
||||||
for (int type : IntStream.concat(IntStream.of(DEFAULT_SORTING_TYPE), Arrays.stream(availableSortingTypes)).toArray())
|
for (int type :
|
||||||
|
IntStream.concat(IntStream.of(DEFAULT_SORTING_TYPE), Arrays.stream(availableSortingTypes)).toArray())
|
||||||
{
|
{
|
||||||
final Row.Builder rowBuilder = new Row.Builder();
|
final Row.Builder rowBuilder = new Row.Builder();
|
||||||
rowBuilder.setTitle(getCarContext().getString(sortingTypeToStringRes(type)));
|
rowBuilder.setTitle(getCarContext().getString(sortingTypeToStringRes(type)));
|
||||||
@@ -148,7 +150,8 @@ class SortingScreen extends BaseMapScreen
|
|||||||
private int getLastAvailableSortingType()
|
private int getLastAvailableSortingType()
|
||||||
{
|
{
|
||||||
int currentType = getLastSortingType();
|
int currentType = getLastSortingType();
|
||||||
@BookmarkManager.SortingType int[] types = getAvailableSortingTypes();
|
@BookmarkManager.SortingType
|
||||||
|
int[] types = getAvailableSortingTypes();
|
||||||
for (@BookmarkManager.SortingType int type : types)
|
for (@BookmarkManager.SortingType int type : types)
|
||||||
{
|
{
|
||||||
if (type == currentType)
|
if (type == currentType)
|
||||||
|
|||||||
@@ -2,11 +2,9 @@ package app.organicmaps.car.screens.download;
|
|||||||
|
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.car.app.model.Action;
|
import androidx.car.app.model.Action;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
@@ -25,7 +23,8 @@ class DownloadMapsForFirstLaunchScreen extends DownloadMapsScreen
|
|||||||
@Override
|
@Override
|
||||||
public void onResume(@NonNull LifecycleOwner owner)
|
public void onResume(@NonNull LifecycleOwner owner)
|
||||||
{
|
{
|
||||||
// Attempting to streamline initial download by including the current country in the list of missing maps for simultaneous retrieval.
|
// Attempting to streamline initial download by including the current country in the list of missing maps for
|
||||||
|
// simultaneous retrieval.
|
||||||
final Location location = MwmApplication.from(getCarContext()).getLocationHelper().getSavedLocation();
|
final Location location = MwmApplication.from(getCarContext()).getLocationHelper().getSavedLocation();
|
||||||
if (location == null)
|
if (location == null)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ package app.organicmaps.car.screens.download;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.car.app.model.Action;
|
import androidx.car.app.model.Action;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.routing.ResultCodesHelper;
|
import app.organicmaps.routing.ResultCodesHelper;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
class DownloadMapsForRouteScreen extends DownloadMapsScreen
|
class DownloadMapsForRouteScreen extends DownloadMapsScreen
|
||||||
@@ -17,8 +15,11 @@ class DownloadMapsForRouteScreen extends DownloadMapsScreen
|
|||||||
{
|
{
|
||||||
super(builder);
|
super(builder);
|
||||||
|
|
||||||
mTitle = ResultCodesHelper.getDialogTitleSubtitle(builder.mCarContext, builder.mResultCode, Objects.requireNonNull(builder.mMissingMaps).length)
|
mTitle = ResultCodesHelper
|
||||||
.getTitleMessage().first;
|
.getDialogTitleSubtitle(builder.mCarContext, builder.mResultCode,
|
||||||
|
Objects.requireNonNull(builder.mMissingMaps).length)
|
||||||
|
.getTitleMessage()
|
||||||
|
.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -35,7 +36,8 @@ class DownloadMapsForRouteScreen extends DownloadMapsScreen
|
|||||||
final int mapsCount = getMissingMaps().size();
|
final int mapsCount = getMissingMaps().size();
|
||||||
if (mapsCount == 1)
|
if (mapsCount == 1)
|
||||||
return DownloaderHelpers.getCountryName(getMissingMaps().get(0)) + "\n" + mapsSize;
|
return DownloaderHelpers.getCountryName(getMissingMaps().get(0)) + "\n" + mapsSize;
|
||||||
return getCarContext().getString(R.string.downloader_status_maps) + " (" + getMissingMaps().size() + "): " + mapsSize;
|
return getCarContext().getString(R.string.downloader_status_maps) + " (" + getMissingMaps().size()
|
||||||
|
+ "): " + mapsSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package app.organicmaps.car.screens.download;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.car.app.model.Action;
|
import androidx.car.app.model.Action;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
|
|
||||||
class DownloadMapsForViewScreen extends DownloadMapsScreen
|
class DownloadMapsForViewScreen extends DownloadMapsScreen
|
||||||
|
|||||||
@@ -7,13 +7,11 @@ import androidx.car.app.model.Header;
|
|||||||
import androidx.car.app.model.MessageTemplate;
|
import androidx.car.app.model.MessageTemplate;
|
||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.screens.base.BaseScreen;
|
import app.organicmaps.car.screens.base.BaseScreen;
|
||||||
import app.organicmaps.car.util.Colors;
|
import app.organicmaps.car.util.Colors;
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
import app.organicmaps.sdk.util.StringUtils;
|
import app.organicmaps.sdk.util.StringUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class DownloadMapsScreen extends BaseScreen
|
public abstract class DownloadMapsScreen extends BaseScreen
|
||||||
@@ -100,10 +98,11 @@ public abstract class DownloadMapsScreen extends BaseScreen
|
|||||||
|
|
||||||
private void onDownload()
|
private void onDownload()
|
||||||
{
|
{
|
||||||
getScreenManager().pushForResult(new DownloaderScreen(getCarContext(), mMissingMaps, mIsCancelActionDisabled), result -> {
|
getScreenManager().pushForResult(new DownloaderScreen(getCarContext(), mMissingMaps, mIsCancelActionDisabled),
|
||||||
setResult(result);
|
result -> {
|
||||||
finish();
|
setResult(result);
|
||||||
});
|
finish();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ package app.organicmaps.car.screens.download;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
|
|
||||||
import app.organicmaps.routing.ResultCodesHelper;
|
import app.organicmaps.routing.ResultCodesHelper;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class DownloadMapsScreenBuilder
|
public class DownloadMapsScreenBuilder
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
package app.organicmaps.car.screens.download;
|
package app.organicmaps.car.screens.download;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.organicmaps.BuildConfig;
|
import app.organicmaps.BuildConfig;
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public final class DownloaderHelpers
|
public final class DownloaderHelpers
|
||||||
{
|
{
|
||||||
static final String[] WORLD_MAPS = new String[]{"World", "WorldCoasts"};
|
static final String[] WORLD_MAPS = new String[] {"World", "WorldCoasts"};
|
||||||
|
|
||||||
// World maps may be missing only in the F-Droid build.
|
// World maps may be missing only in the F-Droid build.
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.car.screens.download;
|
package app.organicmaps.car.screens.download;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
import androidx.car.app.constraints.ConstraintManager;
|
import androidx.car.app.constraints.ConstraintManager;
|
||||||
@@ -10,7 +9,6 @@ import androidx.car.app.model.Header;
|
|||||||
import androidx.car.app.model.MessageTemplate;
|
import androidx.car.app.model.MessageTemplate;
|
||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.screens.ErrorScreen;
|
import app.organicmaps.car.screens.ErrorScreen;
|
||||||
import app.organicmaps.car.screens.base.BaseScreen;
|
import app.organicmaps.car.screens.base.BaseScreen;
|
||||||
@@ -18,7 +16,6 @@ import app.organicmaps.sdk.downloader.CountryItem;
|
|||||||
import app.organicmaps.sdk.downloader.MapManager;
|
import app.organicmaps.sdk.downloader.MapManager;
|
||||||
import app.organicmaps.sdk.util.StringUtils;
|
import app.organicmaps.sdk.util.StringUtils;
|
||||||
import app.organicmaps.sdk.util.concurrency.UiThread;
|
import app.organicmaps.sdk.util.concurrency.UiThread;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -36,8 +33,7 @@ class DownloaderScreen extends BaseScreen
|
|||||||
private boolean mIsDownloadFailed = false;
|
private boolean mIsDownloadFailed = false;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback()
|
private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onStatusChanged(@NonNull final List<MapManager.StorageCallbackData> data)
|
public void onStatusChanged(@NonNull final List<MapManager.StorageCallbackData> data)
|
||||||
{
|
{
|
||||||
@@ -85,7 +81,8 @@ class DownloaderScreen extends BaseScreen
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DownloaderScreen(@NonNull final CarContext carContext, @NonNull final List<CountryItem> missingMaps, final boolean isCancelActionDisabled)
|
DownloaderScreen(@NonNull final CarContext carContext, @NonNull final List<CountryItem> missingMaps,
|
||||||
|
final boolean isCancelActionDisabled)
|
||||||
{
|
{
|
||||||
super(carContext);
|
super(carContext);
|
||||||
setMarker(DownloadMapsScreen.MARKER);
|
setMarker(DownloadMapsScreen.MARKER);
|
||||||
@@ -171,9 +168,9 @@ class DownloaderScreen extends BaseScreen
|
|||||||
{
|
{
|
||||||
mIsDownloadFailed = true;
|
mIsDownloadFailed = true;
|
||||||
final ErrorScreen.Builder builder = new ErrorScreen.Builder(getCarContext())
|
final ErrorScreen.Builder builder = new ErrorScreen.Builder(getCarContext())
|
||||||
.setTitle(R.string.country_status_download_failed)
|
.setTitle(R.string.country_status_download_failed)
|
||||||
.setErrorMessage(MapManager.getErrorCodeStrRes(data.errorCode))
|
.setErrorMessage(MapManager.getErrorCodeStrRes(data.errorCode))
|
||||||
.setPositiveButton(R.string.downloader_retry, null);
|
.setPositiveButton(R.string.downloader_retry, null);
|
||||||
if (!mIsCancelActionDisabled)
|
if (!mIsCancelActionDisabled)
|
||||||
builder.setNegativeButton(R.string.cancel, this::finish);
|
builder.setNegativeButton(R.string.cancel, this::finish);
|
||||||
getScreenManager().push(builder.build());
|
getScreenManager().push(builder.build());
|
||||||
|
|||||||
@@ -7,21 +7,18 @@ import android.content.Intent;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.app.NotificationManagerCompat;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmFragmentActivity;
|
import app.organicmaps.base.BaseMwmFragmentActivity;
|
||||||
import app.organicmaps.sdk.util.LocationUtils;
|
import app.organicmaps.sdk.util.LocationUtils;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class RequestPermissionsActivity extends BaseMwmFragmentActivity
|
public class RequestPermissionsActivity extends BaseMwmFragmentActivity
|
||||||
{
|
{
|
||||||
private static final String[] LOCATION_PERMISSIONS = new String[]{ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION};
|
private static final String[] LOCATION_PERMISSIONS = new String[] {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION};
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ActivityResultLauncher<String[]> mPermissionsRequest;
|
private ActivityResultLauncher<String[]> mPermissionsRequest;
|
||||||
@@ -34,7 +31,7 @@ public class RequestPermissionsActivity extends BaseMwmFragmentActivity
|
|||||||
|
|
||||||
findViewById(R.id.btn_grant_permissions).setOnClickListener(unused -> openAppPermissionSettings());
|
findViewById(R.id.btn_grant_permissions).setOnClickListener(unused -> openAppPermissionSettings());
|
||||||
mPermissionsRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(),
|
mPermissionsRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(),
|
||||||
(grantedPermissions) -> closeIfPermissionsGranted());
|
(grantedPermissions) -> closeIfPermissionsGranted());
|
||||||
mPermissionsRequest.launch(LOCATION_PERMISSIONS);
|
mPermissionsRequest.launch(LOCATION_PERMISSIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,10 @@ import static android.Manifest.permission.POST_NOTIFICATIONS;
|
|||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
import androidx.car.app.Screen;
|
import androidx.car.app.Screen;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
|
||||||
public class RequestPermissionsScreenBuilder
|
public class RequestPermissionsScreenBuilder
|
||||||
@@ -18,8 +16,8 @@ public class RequestPermissionsScreenBuilder
|
|||||||
|
|
||||||
public static Screen build(@NonNull CarContext carContext, @NonNull Runnable permissionsGrantedCallback)
|
public static Screen build(@NonNull CarContext carContext, @NonNull Runnable permissionsGrantedCallback)
|
||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||||
ContextCompat.checkSelfPermission(carContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED)
|
&& ContextCompat.checkSelfPermission(carContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED)
|
||||||
{
|
{
|
||||||
Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, using API-based permissions request");
|
Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, using API-based permissions request");
|
||||||
return new RequestPermissionsScreenWithApi(carContext, permissionsGrantedCallback);
|
return new RequestPermissionsScreenWithApi(carContext, permissionsGrantedCallback);
|
||||||
|
|||||||
@@ -13,14 +13,12 @@ import androidx.car.app.model.ParkedOnlyOnClickListener;
|
|||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.screens.ErrorScreen;
|
import app.organicmaps.car.screens.ErrorScreen;
|
||||||
import app.organicmaps.car.screens.base.BaseScreen;
|
import app.organicmaps.car.screens.base.BaseScreen;
|
||||||
import app.organicmaps.car.util.Colors;
|
import app.organicmaps.car.util.Colors;
|
||||||
import app.organicmaps.car.util.UserActionRequired;
|
import app.organicmaps.car.util.UserActionRequired;
|
||||||
import app.organicmaps.sdk.util.LocationUtils;
|
import app.organicmaps.sdk.util.LocationUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -41,19 +39,23 @@ public class RequestPermissionsScreenWithApi extends BaseScreen implements UserA
|
|||||||
@Override
|
@Override
|
||||||
public Template onGetTemplate()
|
public Template onGetTemplate()
|
||||||
{
|
{
|
||||||
final MessageTemplate.Builder builder = new MessageTemplate.Builder(getCarContext().getString(R.string.aa_request_permission_activity_text));
|
final MessageTemplate.Builder builder =
|
||||||
final Action grantPermissions = new Action.Builder()
|
new MessageTemplate.Builder(getCarContext().getString(R.string.aa_request_permission_activity_text));
|
||||||
.setTitle(getCarContext().getString(R.string.aa_grant_permissions))
|
final Action grantPermissions =
|
||||||
.setBackgroundColor(Colors.BUTTON_ACCEPT)
|
new Action.Builder()
|
||||||
.setOnClickListener(ParkedOnlyOnClickListener.create(() -> getCarContext().requestPermissions(LOCATION_PERMISSIONS, this::onRequestPermissionsResult)))
|
.setTitle(getCarContext().getString(R.string.aa_grant_permissions))
|
||||||
.build();
|
.setBackgroundColor(Colors.BUTTON_ACCEPT)
|
||||||
|
.setOnClickListener(ParkedOnlyOnClickListener.create(
|
||||||
|
() -> getCarContext().requestPermissions(LOCATION_PERMISSIONS, this::onRequestPermissionsResult)))
|
||||||
|
.build();
|
||||||
|
|
||||||
final Header.Builder headerBuilder = new Header.Builder();
|
final Header.Builder headerBuilder = new Header.Builder();
|
||||||
headerBuilder.setStartHeaderAction(Action.APP_ICON);
|
headerBuilder.setStartHeaderAction(Action.APP_ICON);
|
||||||
headerBuilder.setTitle(getCarContext().getString(R.string.app_name));
|
headerBuilder.setTitle(getCarContext().getString(R.string.app_name));
|
||||||
|
|
||||||
builder.setHeader(headerBuilder.build());
|
builder.setHeader(headerBuilder.build());
|
||||||
builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_location_off)).build());
|
builder.setIcon(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_location_off)).build());
|
||||||
builder.addAction(grantPermissions);
|
builder.addAction(grantPermissions);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
@@ -70,19 +72,19 @@ public class RequestPermissionsScreenWithApi extends BaseScreen implements UserA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onRequestPermissionsResult(@NonNull List<String> grantedPermissions, @NonNull List<String> rejectedPermissions)
|
private void onRequestPermissionsResult(@NonNull List<String> grantedPermissions,
|
||||||
|
@NonNull List<String> rejectedPermissions)
|
||||||
{
|
{
|
||||||
if (grantedPermissions.isEmpty())
|
if (grantedPermissions.isEmpty())
|
||||||
{
|
{
|
||||||
getScreenManager().push(new ErrorScreen.Builder(getCarContext())
|
getScreenManager().push(new ErrorScreen.Builder(getCarContext())
|
||||||
.setErrorMessage(R.string.location_is_disabled_long_text)
|
.setErrorMessage(R.string.location_is_disabled_long_text)
|
||||||
.setNegativeButton(R.string.close, null)
|
.setNegativeButton(R.string.close, null)
|
||||||
.build()
|
.build());
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPermissionsGrantedCallback.run();
|
mPermissionsGrantedCallback.run();
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import android.app.NotificationManager;
|
|||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.RequiresPermission;
|
import androidx.annotation.RequiresPermission;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -19,7 +18,6 @@ import androidx.core.app.NotificationManagerCompat;
|
|||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.CarAppService;
|
import app.organicmaps.car.CarAppService;
|
||||||
import app.organicmaps.car.screens.base.BaseScreen;
|
import app.organicmaps.car.screens.base.BaseScreen;
|
||||||
@@ -27,7 +25,6 @@ import app.organicmaps.car.util.UserActionRequired;
|
|||||||
import app.organicmaps.sdk.util.LocationUtils;
|
import app.organicmaps.sdk.util.LocationUtils;
|
||||||
import app.organicmaps.sdk.util.concurrency.ThreadPool;
|
import app.organicmaps.sdk.util.concurrency.ThreadPool;
|
||||||
import app.organicmaps.sdk.util.concurrency.UiThread;
|
import app.organicmaps.sdk.util.concurrency.UiThread;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
public class RequestPermissionsScreenWithNotification extends BaseScreen implements UserActionRequired
|
public class RequestPermissionsScreenWithNotification extends BaseScreen implements UserActionRequired
|
||||||
@@ -40,7 +37,8 @@ public class RequestPermissionsScreenWithNotification extends BaseScreen impleme
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final Runnable mPermissionsGrantedCallback;
|
private final Runnable mPermissionsGrantedCallback;
|
||||||
|
|
||||||
public RequestPermissionsScreenWithNotification(@NonNull CarContext carContext, @NonNull Runnable permissionsGrantedCallback)
|
public RequestPermissionsScreenWithNotification(@NonNull CarContext carContext,
|
||||||
|
@NonNull Runnable permissionsGrantedCallback)
|
||||||
{
|
{
|
||||||
super(carContext);
|
super(carContext);
|
||||||
mBackgroundExecutor = ThreadPool.getWorker();
|
mBackgroundExecutor = ThreadPool.getWorker();
|
||||||
@@ -51,14 +49,16 @@ public class RequestPermissionsScreenWithNotification extends BaseScreen impleme
|
|||||||
@Override
|
@Override
|
||||||
public Template onGetTemplate()
|
public Template onGetTemplate()
|
||||||
{
|
{
|
||||||
final MessageTemplate.Builder builder = new MessageTemplate.Builder(getCarContext().getString(R.string.aa_location_permissions_request));
|
final MessageTemplate.Builder builder =
|
||||||
|
new MessageTemplate.Builder(getCarContext().getString(R.string.aa_location_permissions_request));
|
||||||
|
|
||||||
final Header.Builder headerBuilder = new Header.Builder();
|
final Header.Builder headerBuilder = new Header.Builder();
|
||||||
headerBuilder.setStartHeaderAction(Action.APP_ICON);
|
headerBuilder.setStartHeaderAction(Action.APP_ICON);
|
||||||
headerBuilder.setTitle(getCarContext().getString(R.string.aa_grant_permissions));
|
headerBuilder.setTitle(getCarContext().getString(R.string.aa_grant_permissions));
|
||||||
builder.setHeader(headerBuilder.build());
|
builder.setHeader(headerBuilder.build());
|
||||||
|
|
||||||
builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_location_off)).build());
|
builder.setIcon(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_location_off)).build());
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,9 +105,10 @@ public class RequestPermissionsScreenWithNotification extends BaseScreen impleme
|
|||||||
final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE;
|
final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE;
|
||||||
final Intent contentIntent = new Intent(getCarContext(), RequestPermissionsActivity.class);
|
final Intent contentIntent = new Intent(getCarContext(), RequestPermissionsActivity.class);
|
||||||
final PendingIntent pendingIntent = PendingIntent.getActivity(getCarContext(), 0, contentIntent,
|
final PendingIntent pendingIntent = PendingIntent.getActivity(getCarContext(), 0, contentIntent,
|
||||||
PendingIntent.FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE);
|
PendingIntent.FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE);
|
||||||
|
|
||||||
final NotificationCompat.Builder builder = new NotificationCompat.Builder(getCarContext(), CarAppService.ANDROID_AUTO_NOTIFICATION_CHANNEL_ID);
|
final NotificationCompat.Builder builder =
|
||||||
|
new NotificationCompat.Builder(getCarContext(), CarAppService.ANDROID_AUTO_NOTIFICATION_CHANNEL_ID);
|
||||||
builder.setCategory(NotificationCompat.CATEGORY_NAVIGATION)
|
builder.setCategory(NotificationCompat.CATEGORY_NAVIGATION)
|
||||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.car.screens.search;
|
package app.organicmaps.car.screens.search;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -16,15 +15,14 @@ import androidx.car.app.model.Template;
|
|||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
import app.organicmaps.sdk.search.SearchListener;
|
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||||
import app.organicmaps.sdk.search.SearchEngine;
|
import app.organicmaps.sdk.search.SearchEngine;
|
||||||
|
import app.organicmaps.sdk.search.SearchListener;
|
||||||
import app.organicmaps.sdk.search.SearchRecents;
|
import app.organicmaps.sdk.search.SearchRecents;
|
||||||
import app.organicmaps.sdk.search.SearchResult;
|
import app.organicmaps.sdk.search.SearchResult;
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
@@ -125,8 +123,12 @@ public class SearchOnMapScreen extends BaseMapScreen implements SearchListener
|
|||||||
{
|
{
|
||||||
builder.setBrowsable(true);
|
builder.setBrowsable(true);
|
||||||
builder.setTitle(result.suggestion);
|
builder.setTitle(result.suggestion);
|
||||||
builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build());
|
builder.setImage(
|
||||||
builder.setOnClickListener(() -> getScreenManager().push(new Builder(getCarContext(), getSurfaceRenderer()).setQuery(result.suggestion).build()));
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build());
|
||||||
|
builder.setOnClickListener(
|
||||||
|
()
|
||||||
|
-> getScreenManager().push(
|
||||||
|
new Builder(getCarContext(), getSurfaceRenderer()).setQuery(result.suggestion).build()));
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
@@ -147,7 +149,8 @@ public class SearchOnMapScreen extends BaseMapScreen implements SearchListener
|
|||||||
final double lat = hasLocation ? location.getLat() : 0;
|
final double lat = hasLocation ? location.getLat() : 0;
|
||||||
final double lon = hasLocation ? location.getLon() : 0;
|
final double lon = hasLocation ? location.getLon() : 0;
|
||||||
|
|
||||||
SearchEngine.INSTANCE.searchInteractive(mQuery, mIsCategory, mLocale, System.nanoTime(), true /* isMapAndTable */, hasLocation, lat, lon);
|
SearchEngine.INSTANCE.searchInteractive(mQuery, mIsCategory, mLocale, System.nanoTime(), true /* isMapAndTable */,
|
||||||
|
hasLocation, lat, lon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.car.screens.search;
|
package app.organicmaps.car.screens.search;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -15,14 +14,13 @@ import androidx.car.app.model.SearchTemplate;
|
|||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.sdk.search.SearchListener;
|
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||||
import app.organicmaps.sdk.search.SearchEngine;
|
import app.organicmaps.sdk.search.SearchEngine;
|
||||||
|
import app.organicmaps.sdk.search.SearchListener;
|
||||||
import app.organicmaps.sdk.search.SearchRecents;
|
import app.organicmaps.sdk.search.SearchRecents;
|
||||||
import app.organicmaps.sdk.search.SearchResult;
|
import app.organicmaps.sdk.search.SearchResult;
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
@@ -137,10 +135,9 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search
|
|||||||
if (result.type == SearchResult.TYPE_RESULT)
|
if (result.type == SearchResult.TYPE_RESULT)
|
||||||
{
|
{
|
||||||
final String title = result.getTitle(getCarContext());
|
final String title = result.getTitle(getCarContext());
|
||||||
final CharSequence description = SearchUiHelpers.concatenateStrings(
|
final CharSequence description =
|
||||||
SearchUiHelpers.getDistanceText(result),
|
SearchUiHelpers.concatenateStrings(SearchUiHelpers.getDistanceText(result), result.description.description,
|
||||||
result.description.description,
|
SearchUiHelpers.getOpeningHoursText(getCarContext(), result));
|
||||||
SearchUiHelpers.getOpeningHoursText(getCarContext(), result));
|
|
||||||
final String region = result.description.region;
|
final String region = result.description.region;
|
||||||
builder.setTitle(title);
|
builder.setTitle(title);
|
||||||
if (!TextUtils.isEmpty(description))
|
if (!TextUtils.isEmpty(description))
|
||||||
@@ -158,7 +155,8 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search
|
|||||||
{
|
{
|
||||||
builder.setBrowsable(true);
|
builder.setBrowsable(true);
|
||||||
builder.setTitle(result.suggestion);
|
builder.setTitle(result.suggestion);
|
||||||
builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build());
|
builder.setImage(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build());
|
||||||
builder.setOnClickListener(() -> onSearchSubmitted(result.suggestion));
|
builder.setOnClickListener(() -> onSearchSubmitted(result.suggestion));
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
@@ -166,7 +164,8 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search
|
|||||||
|
|
||||||
private boolean loadRecents()
|
private boolean loadRecents()
|
||||||
{
|
{
|
||||||
final CarIcon iconRecent = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search_recent)).build();
|
final CarIcon iconRecent =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search_recent)).build();
|
||||||
|
|
||||||
final ItemList.Builder builder = new ItemList.Builder();
|
final ItemList.Builder builder = new ItemList.Builder();
|
||||||
builder.setNoItemsMessage(getCarContext().getString(R.string.search_history_text));
|
builder.setNoItemsMessage(getCarContext().getString(R.string.search_history_text));
|
||||||
@@ -190,9 +189,14 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search
|
|||||||
private ActionStrip createActionStrip()
|
private ActionStrip createActionStrip()
|
||||||
{
|
{
|
||||||
final Action.Builder builder = new Action.Builder();
|
final Action.Builder builder = new Action.Builder();
|
||||||
builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_show_on_map)).build());
|
builder.setIcon(
|
||||||
builder.setOnClickListener(() ->
|
new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_show_on_map)).build());
|
||||||
getScreenManager().push(new SearchOnMapScreen.Builder(getCarContext(), getSurfaceRenderer()).setQuery(mQuery).setLocale(mLocale).build()));
|
builder.setOnClickListener(
|
||||||
|
()
|
||||||
|
-> getScreenManager().push(new SearchOnMapScreen.Builder(getCarContext(), getSurfaceRenderer())
|
||||||
|
.setQuery(mQuery)
|
||||||
|
.setLocale(mLocale)
|
||||||
|
.build()));
|
||||||
|
|
||||||
return new ActionStrip.Builder().addAction(builder.build()).build();
|
return new ActionStrip.Builder().addAction(builder.build()).build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,18 +3,15 @@ package app.organicmaps.car.screens.search;
|
|||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
import androidx.car.app.model.CarColor;
|
import androidx.car.app.model.CarColor;
|
||||||
import androidx.car.app.model.DistanceSpan;
|
import androidx.car.app.model.DistanceSpan;
|
||||||
import androidx.car.app.model.ForegroundCarColorSpan;
|
import androidx.car.app.model.ForegroundCarColorSpan;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.util.Colors;
|
import app.organicmaps.car.util.Colors;
|
||||||
import app.organicmaps.car.util.RoutingHelpers;
|
import app.organicmaps.car.util.RoutingHelpers;
|
||||||
import app.organicmaps.sdk.search.SearchResult;
|
import app.organicmaps.sdk.search.SearchResult;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -50,7 +47,8 @@ public final class SearchUiHelpers
|
|||||||
return "";
|
return "";
|
||||||
|
|
||||||
final SpannableStringBuilder distance = new SpannableStringBuilder(" ");
|
final SpannableStringBuilder distance = new SpannableStringBuilder(" ");
|
||||||
distance.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(searchResult.description.distance)), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
distance.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(searchResult.description.distance)), 0, 1,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
distance.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
distance.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
@@ -64,31 +62,29 @@ public final class SearchUiHelpers
|
|||||||
CarColor color = Colors.DEFAULT;
|
CarColor color = Colors.DEFAULT;
|
||||||
switch (searchResult.description.openNow)
|
switch (searchResult.description.openNow)
|
||||||
{
|
{
|
||||||
case SearchResult.OPEN_NOW_YES:
|
case SearchResult.OPEN_NOW_YES:
|
||||||
if (searchResult.description.minutesUntilClosed < 60) // less than 1 hour
|
if (searchResult.description.minutesUntilClosed < 60) // less than 1 hour
|
||||||
{
|
{
|
||||||
final String time = searchResult.description.minutesUntilClosed + " " +
|
final String time = searchResult.description.minutesUntilClosed + " " + carContext.getString(R.string.minute);
|
||||||
carContext.getString(R.string.minute);
|
text = carContext.getString(R.string.closes_in, time);
|
||||||
text = carContext.getString(R.string.closes_in, time);
|
color = Colors.OPENING_HOURS_CLOSES_SOON;
|
||||||
color = Colors.OPENING_HOURS_CLOSES_SOON;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
text = carContext.getString(R.string.editor_time_open);
|
||||||
text = carContext.getString(R.string.editor_time_open);
|
color = Colors.OPENING_HOURS_OPEN;
|
||||||
color = Colors.OPENING_HOURS_OPEN;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case SearchResult.OPEN_NOW_NO:
|
||||||
case SearchResult.OPEN_NOW_NO:
|
if (searchResult.description.minutesUntilOpen < 60) // less than 1 hour
|
||||||
if (searchResult.description.minutesUntilOpen < 60) // less than 1 hour
|
{
|
||||||
{
|
final String time = searchResult.description.minutesUntilOpen + " " + carContext.getString(R.string.minute);
|
||||||
final String time = searchResult.description.minutesUntilOpen + " " +
|
text = carContext.getString(R.string.opens_in, time);
|
||||||
carContext.getString(R.string.minute);
|
}
|
||||||
text = carContext.getString(R.string.opens_in, time);
|
else
|
||||||
}
|
text = carContext.getString(R.string.closed);
|
||||||
else
|
color = Colors.OPENING_HOURS_CLOSED;
|
||||||
text = carContext.getString(R.string.closed);
|
break;
|
||||||
color = Colors.OPENING_HOURS_CLOSED;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append(text);
|
result.append(text);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import androidx.car.app.model.Row;
|
|||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
@@ -20,7 +19,6 @@ import app.organicmaps.car.util.Toggle;
|
|||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
import app.organicmaps.sdk.routing.RoutingOptions;
|
import app.organicmaps.sdk.routing.RoutingOptions;
|
||||||
import app.organicmaps.sdk.settings.RoadType;
|
import app.organicmaps.sdk.settings.RoadType;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -28,16 +26,12 @@ public class DrivingOptionsScreen extends BaseMapScreen
|
|||||||
{
|
{
|
||||||
public static final Object DRIVING_OPTIONS_RESULT_CHANGED = 0x1;
|
public static final Object DRIVING_OPTIONS_RESULT_CHANGED = 0x1;
|
||||||
|
|
||||||
private record DrivingOption(RoadType roadType, @StringRes int text)
|
private record DrivingOption(RoadType roadType, @StringRes int text) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private final DrivingOption[] mDrivingOptions = {
|
private final DrivingOption[] mDrivingOptions = {new DrivingOption(RoadType.Toll, R.string.avoid_tolls),
|
||||||
new DrivingOption(RoadType.Toll, R.string.avoid_tolls),
|
new DrivingOption(RoadType.Dirty, R.string.avoid_unpaved),
|
||||||
new DrivingOption(RoadType.Dirty, R.string.avoid_unpaved),
|
new DrivingOption(RoadType.Ferry, R.string.avoid_ferry),
|
||||||
new DrivingOption(RoadType.Ferry, R.string.avoid_ferry),
|
new DrivingOption(RoadType.Motorway, R.string.avoid_motorways)};
|
||||||
new DrivingOption(RoadType.Motorway, R.string.avoid_motorways)
|
|
||||||
};
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Map<RoadType, Boolean> mInitialDrivingOptionsState = new HashMap<>();
|
private final Map<RoadType, Boolean> mInitialDrivingOptionsState = new HashMap<>();
|
||||||
@@ -64,7 +58,8 @@ public class DrivingOptionsScreen extends BaseMapScreen
|
|||||||
{
|
{
|
||||||
for (final DrivingOption drivingOption : mDrivingOptions)
|
for (final DrivingOption drivingOption : mDrivingOptions)
|
||||||
{
|
{
|
||||||
if (Boolean.TRUE.equals(mInitialDrivingOptionsState.get(drivingOption.roadType)) != RoutingOptions.hasOption(drivingOption.roadType))
|
if (Boolean.TRUE.equals(mInitialDrivingOptionsState.get(drivingOption.roadType))
|
||||||
|
!= RoutingOptions.hasOption(drivingOption.roadType))
|
||||||
{
|
{
|
||||||
setResult(DRIVING_OPTIONS_RESULT_CHANGED);
|
setResult(DRIVING_OPTIONS_RESULT_CHANGED);
|
||||||
return;
|
return;
|
||||||
@@ -93,7 +88,8 @@ public class DrivingOptionsScreen extends BaseMapScreen
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Row createDrivingOptionsToggle(RoadType roadType, @StringRes int title)
|
private Row createDrivingOptionsToggle(RoadType roadType, @StringRes int title)
|
||||||
{
|
{
|
||||||
final OnClickListener listener = () -> {
|
final OnClickListener listener = () ->
|
||||||
|
{
|
||||||
if (RoutingOptions.hasOption(roadType))
|
if (RoutingOptions.hasOption(roadType))
|
||||||
RoutingOptions.removeOption(roadType);
|
RoutingOptions.removeOption(roadType);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -10,13 +10,12 @@ import androidx.car.app.model.ListTemplate;
|
|||||||
import androidx.car.app.model.Row;
|
import androidx.car.app.model.Row;
|
||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
|
|
||||||
import app.organicmaps.BuildConfig;
|
import app.organicmaps.BuildConfig;
|
||||||
import app.organicmaps.sdk.Framework;
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
|
import app.organicmaps.sdk.Framework;
|
||||||
import app.organicmaps.sdk.util.DateUtils;
|
import app.organicmaps.sdk.util.DateUtils;
|
||||||
|
|
||||||
public class HelpScreen extends BaseMapScreen
|
public class HelpScreen extends BaseMapScreen
|
||||||
|
|||||||
@@ -12,14 +12,13 @@ import androidx.car.app.model.OnClickListener;
|
|||||||
import androidx.car.app.model.Row;
|
import androidx.car.app.model.Row;
|
||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
|
|
||||||
import app.organicmaps.sdk.Framework;
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.util.ThemeUtils;
|
import app.organicmaps.car.util.ThemeUtils;
|
||||||
import app.organicmaps.car.util.Toggle;
|
import app.organicmaps.car.util.Toggle;
|
||||||
import app.organicmaps.car.util.UiHelpers;
|
import app.organicmaps.car.util.UiHelpers;
|
||||||
|
import app.organicmaps.sdk.Framework;
|
||||||
import app.organicmaps.sdk.util.Config;
|
import app.organicmaps.sdk.util.Config;
|
||||||
|
|
||||||
public class SettingsScreen extends BaseMapScreen
|
public class SettingsScreen extends BaseMapScreen
|
||||||
@@ -66,7 +65,8 @@ public class SettingsScreen extends BaseMapScreen
|
|||||||
builder.addItem(createRoutingOptionsItem());
|
builder.addItem(createRoutingOptionsItem());
|
||||||
builder.addItem(create3dBuildingsItem());
|
builder.addItem(create3dBuildingsItem());
|
||||||
builder.addItem(createSharedPrefsToggle(R.string.big_font, Config::isLargeFontsSize, Config::setLargeFontsSize));
|
builder.addItem(createSharedPrefsToggle(R.string.big_font, Config::isLargeFontsSize, Config::setLargeFontsSize));
|
||||||
builder.addItem(createSharedPrefsToggle(R.string.transliteration_title, Config::isTransliteration, Config::setTransliteration));
|
builder.addItem(
|
||||||
|
createSharedPrefsToggle(R.string.transliteration_title, Config::isTransliteration, Config::setTransliteration));
|
||||||
builder.addItem(createHelpItem());
|
builder.addItem(createHelpItem());
|
||||||
return new ListTemplate.Builder().setHeader(createHeader()).setSingleList(builder.build()).build();
|
return new ListTemplate.Builder().setHeader(createHeader()).setSingleList(builder.build()).build();
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,10 @@ public class SettingsScreen extends BaseMapScreen
|
|||||||
{
|
{
|
||||||
final Row.Builder builder = new Row.Builder();
|
final Row.Builder builder = new Row.Builder();
|
||||||
builder.setTitle(getCarContext().getString(R.string.driving_options_title));
|
builder.setTitle(getCarContext().getString(R.string.driving_options_title));
|
||||||
builder.setOnClickListener(() -> getScreenManager().pushForResult(new DrivingOptionsScreen(getCarContext(), getSurfaceRenderer()), this::setResult));
|
builder.setOnClickListener(
|
||||||
|
()
|
||||||
|
-> getScreenManager().pushForResult(new DrivingOptionsScreen(getCarContext(), getSurfaceRenderer()),
|
||||||
|
this::setResult));
|
||||||
builder.setBrowsable(true);
|
builder.setBrowsable(true);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
@@ -98,7 +101,8 @@ public class SettingsScreen extends BaseMapScreen
|
|||||||
final Framework.Params3dMode _3d = new Framework.Params3dMode();
|
final Framework.Params3dMode _3d = new Framework.Params3dMode();
|
||||||
Framework.nativeGet3dMode(_3d);
|
Framework.nativeGet3dMode(_3d);
|
||||||
|
|
||||||
final OnClickListener listener = () -> {
|
final OnClickListener listener = () ->
|
||||||
|
{
|
||||||
Framework.nativeSet3dMode(_3d.enabled, !_3d.buildings);
|
Framework.nativeSet3dMode(_3d.enabled, !_3d.buildings);
|
||||||
invalidate();
|
invalidate();
|
||||||
};
|
};
|
||||||
@@ -119,7 +123,8 @@ public class SettingsScreen extends BaseMapScreen
|
|||||||
private Row createSharedPrefsToggle(@StringRes int titleRes, @NonNull PrefsGetter getter, @NonNull PrefsSetter setter)
|
private Row createSharedPrefsToggle(@StringRes int titleRes, @NonNull PrefsGetter getter, @NonNull PrefsSetter setter)
|
||||||
{
|
{
|
||||||
final boolean enabled = getter.get();
|
final boolean enabled = getter.get();
|
||||||
final OnClickListener listener = () -> {
|
final OnClickListener listener = () ->
|
||||||
|
{
|
||||||
setter.set(!enabled);
|
setter.set(!enabled);
|
||||||
invalidate();
|
invalidate();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import androidx.car.app.model.Row;
|
|||||||
import androidx.car.app.model.Template;
|
import androidx.car.app.model.Template;
|
||||||
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
import androidx.car.app.navigation.model.MapWithContentTemplate;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
@@ -28,8 +27,10 @@ public class ThemeScreen extends BaseMapScreen
|
|||||||
public ThemeScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer)
|
public ThemeScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer)
|
||||||
{
|
{
|
||||||
super(carContext, surfaceRenderer);
|
super(carContext, surfaceRenderer);
|
||||||
mRadioButtonIcon = new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_unchecked)).build();
|
mRadioButtonIcon =
|
||||||
mRadioButtonSelectedIcon = new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_checked)).build();
|
new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_unchecked)).build();
|
||||||
|
mRadioButtonSelectedIcon =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_checked)).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package app.organicmaps.car.util;
|
|||||||
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||||
|
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.RequiresPermission;
|
import androidx.annotation.RequiresPermission;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -13,11 +12,9 @@ import androidx.car.app.hardware.info.CarHardwareLocation;
|
|||||||
import androidx.car.app.hardware.info.CarSensors;
|
import androidx.car.app.hardware.info.CarSensors;
|
||||||
import androidx.car.app.hardware.info.Compass;
|
import androidx.car.app.hardware.info.Compass;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import app.organicmaps.sdk.Map;
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
|
import app.organicmaps.sdk.Map;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@@ -53,7 +50,8 @@ public class CarSensorsManager
|
|||||||
MwmApplication.from(mCarContext).getLocationHelper().start();
|
MwmApplication.from(mCarContext).getLocationHelper().start();
|
||||||
|
|
||||||
if (mIsCarLocationUsed)
|
if (mIsCarLocationUsed)
|
||||||
mCarSensors.addCarHardwareLocationListener(CarSensors.UPDATE_RATE_FASTEST, executor, this::onCarLocationDataAvailable);
|
mCarSensors.addCarHardwareLocationListener(CarSensors.UPDATE_RATE_FASTEST, executor,
|
||||||
|
this::onCarLocationDataAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStop()
|
public void onStop()
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
package app.organicmaps.car.util;
|
package app.organicmaps.car.util;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
import androidx.car.app.ScreenManager;
|
import androidx.car.app.ScreenManager;
|
||||||
|
|
||||||
import app.organicmaps.car.screens.download.DownloadMapsScreen;
|
import app.organicmaps.car.screens.download.DownloadMapsScreen;
|
||||||
import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder;
|
import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder;
|
||||||
|
import app.organicmaps.routing.RoutingController;
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
import app.organicmaps.sdk.downloader.MapManager;
|
import app.organicmaps.sdk.downloader.MapManager;
|
||||||
import app.organicmaps.routing.RoutingController;
|
|
||||||
|
|
||||||
public class CurrentCountryChangedListener implements MapManager.CurrentCountryChangedListener
|
public class CurrentCountryChangedListener implements MapManager.CurrentCountryChangedListener
|
||||||
{
|
{
|
||||||
@@ -45,12 +43,10 @@ public class CurrentCountryChangedListener implements MapManager.CurrentCountryC
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
mPreviousCountryId = countryId;
|
mPreviousCountryId = countryId;
|
||||||
screenManager.push(
|
screenManager.push(new DownloadMapsScreenBuilder(mCarContext)
|
||||||
new DownloadMapsScreenBuilder(mCarContext)
|
.setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.View)
|
||||||
.setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.View)
|
.setMissingMaps(new String[] {countryId})
|
||||||
.setMissingMaps(new String[]{countryId})
|
.build());
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStart(@NonNull final CarContext carContext)
|
public void onStart(@NonNull final CarContext carContext)
|
||||||
|
|||||||
@@ -4,25 +4,23 @@ import android.app.PendingIntent;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
import androidx.car.app.Screen;
|
import androidx.car.app.Screen;
|
||||||
import androidx.car.app.ScreenManager;
|
import androidx.car.app.ScreenManager;
|
||||||
import androidx.car.app.notification.CarPendingIntent;
|
import androidx.car.app.notification.CarPendingIntent;
|
||||||
|
|
||||||
import app.organicmaps.sdk.Framework;
|
|
||||||
import app.organicmaps.sdk.Map;
|
|
||||||
import app.organicmaps.api.Const;
|
import app.organicmaps.api.Const;
|
||||||
import app.organicmaps.sdk.api.ParsedSearchRequest;
|
|
||||||
import app.organicmaps.sdk.api.RequestType;
|
|
||||||
import app.organicmaps.car.CarAppService;
|
import app.organicmaps.car.CarAppService;
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.NavigationScreen;
|
import app.organicmaps.car.screens.NavigationScreen;
|
||||||
import app.organicmaps.car.screens.search.SearchScreen;
|
import app.organicmaps.car.screens.search.SearchScreen;
|
||||||
|
import app.organicmaps.routing.RoutingController;
|
||||||
|
import app.organicmaps.sdk.Framework;
|
||||||
|
import app.organicmaps.sdk.Map;
|
||||||
|
import app.organicmaps.sdk.api.ParsedSearchRequest;
|
||||||
|
import app.organicmaps.sdk.api.RequestType;
|
||||||
import app.organicmaps.sdk.display.DisplayManager;
|
import app.organicmaps.sdk.display.DisplayManager;
|
||||||
import app.organicmaps.sdk.display.DisplayType;
|
import app.organicmaps.sdk.display.DisplayType;
|
||||||
import app.organicmaps.routing.RoutingController;
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
|
||||||
public final class IntentUtils
|
public final class IntentUtils
|
||||||
@@ -31,7 +29,8 @@ public final class IntentUtils
|
|||||||
|
|
||||||
private static final int SEARCH_IN_VIEWPORT_ZOOM = 16;
|
private static final int SEARCH_IN_VIEWPORT_ZOOM = 16;
|
||||||
|
|
||||||
public static void processIntent(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, @NonNull Intent intent)
|
public static void processIntent(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer,
|
||||||
|
@NonNull Intent intent)
|
||||||
{
|
{
|
||||||
final String action = intent.getAction();
|
final String action = intent.getAction();
|
||||||
if (CarContext.ACTION_NAVIGATE.equals(action))
|
if (CarContext.ACTION_NAVIGATE.equals(action))
|
||||||
@@ -50,10 +49,11 @@ public final class IntentUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://developer.android.com/reference/androidx/car/app/CarContext#startCarApp(android.content.Intent)
|
// https://developer.android.com/reference/androidx/car/app/CarContext#startCarApp(android.content.Intent)
|
||||||
private static void processNavigationIntent(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, @NonNull Intent intent)
|
private static void processNavigationIntent(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer,
|
||||||
|
@NonNull Intent intent)
|
||||||
{
|
{
|
||||||
// TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during navigation or route planning.
|
// TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during
|
||||||
// Skip navigation intents during navigation
|
// navigation or route planning. Skip navigation intents during navigation
|
||||||
if (RoutingController.get().isNavigating())
|
if (RoutingController.get().isNavigating())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -64,52 +64,43 @@ public final class IntentUtils
|
|||||||
final ScreenManager screenManager = carContext.getCarService(ScreenManager.class);
|
final ScreenManager screenManager = carContext.getCarService(ScreenManager.class);
|
||||||
switch (Framework.nativeParseAndSetApiUrl(uri.toString()))
|
switch (Framework.nativeParseAndSetApiUrl(uri.toString()))
|
||||||
{
|
{
|
||||||
case RequestType.INCORRECT:
|
case RequestType.INCORRECT: return;
|
||||||
return;
|
case RequestType.MAP:
|
||||||
case RequestType.MAP:
|
screenManager.popToRoot();
|
||||||
screenManager.popToRoot();
|
Map.executeMapApiRequest();
|
||||||
Map.executeMapApiRequest();
|
return;
|
||||||
return;
|
case RequestType.SEARCH:
|
||||||
case RequestType.SEARCH:
|
screenManager.popToRoot();
|
||||||
screenManager.popToRoot();
|
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
|
||||||
final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest();
|
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
|
||||||
final double[] latlon = Framework.nativeGetParsedCenterLatLon();
|
if (latlon != null)
|
||||||
if (latlon != null)
|
{
|
||||||
{
|
Framework.nativeStopLocationFollow();
|
||||||
Framework.nativeStopLocationFollow();
|
Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
|
||||||
Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
|
// We need to update viewport for search api manually because of drape engine
|
||||||
// We need to update viewport for search api manually because of drape engine
|
// will not notify subscribers when search activity is shown.
|
||||||
// will not notify subscribers when search activity is shown.
|
if (!request.mIsSearchOnMap)
|
||||||
if (!request.mIsSearchOnMap)
|
Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
|
||||||
Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM);
|
}
|
||||||
}
|
final SearchScreen.Builder builder = new SearchScreen.Builder(carContext, surfaceRenderer);
|
||||||
final SearchScreen.Builder builder = new SearchScreen.Builder(carContext, surfaceRenderer);
|
builder.setQuery(request.mQuery);
|
||||||
builder.setQuery(request.mQuery);
|
if (request.mLocale != null)
|
||||||
if (request.mLocale != null)
|
builder.setLocale(request.mLocale);
|
||||||
builder.setLocale(request.mLocale);
|
|
||||||
|
|
||||||
screenManager.popToRoot();
|
screenManager.popToRoot();
|
||||||
screenManager.push(builder.build());
|
screenManager.push(builder.build());
|
||||||
return;
|
return;
|
||||||
case RequestType.ROUTE:
|
case RequestType.ROUTE: Logger.e(TAG, "Route API is not supported by Android Auto: " + uri); return;
|
||||||
Logger.e(TAG, "Route API is not supported by Android Auto: " + uri);
|
case RequestType.CROSSHAIR: Logger.e(TAG, "Crosshair API is not supported by Android Auto: " + uri); return;
|
||||||
return;
|
case RequestType.MENU: Logger.e(TAG, "Menu API is not supported by Android Auto: " + uri); return;
|
||||||
case RequestType.CROSSHAIR:
|
case RequestType.SETTINGS: Logger.e(TAG, "Settings API is not supported by Android Auto: " + uri);
|
||||||
Logger.e(TAG, "Crosshair API is not supported by Android Auto: " + uri);
|
|
||||||
return;
|
|
||||||
case RequestType.MENU:
|
|
||||||
Logger.e(TAG, "Menu API is not supported by Android Auto: " + uri);
|
|
||||||
return;
|
|
||||||
case RequestType.SETTINGS:
|
|
||||||
Logger.e(TAG, "Settings API is not supported by Android Auto: " + uri);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processViewIntent(@NonNull CarContext carContext, @NonNull Intent intent)
|
private static void processViewIntent(@NonNull CarContext carContext, @NonNull Intent intent)
|
||||||
{
|
{
|
||||||
final Uri uri = intent.getData();
|
final Uri uri = intent.getData();
|
||||||
if (uri != null
|
if (uri != null && Const.API_SCHEME.equals(uri.getScheme())
|
||||||
&& Const.API_SCHEME.equals(uri.getScheme())
|
|
||||||
&& CarAppService.API_CAR_HOST.equals(uri.getSchemeSpecificPart())
|
&& CarAppService.API_CAR_HOST.equals(uri.getSchemeSpecificPart())
|
||||||
&& CarAppService.ACTION_SHOW_NAVIGATION_SCREEN.equals(uri.getFragment()))
|
&& CarAppService.ACTION_SHOW_NAVIGATION_SCREEN.equals(uri.getFragment()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import androidx.car.app.model.Distance;
|
|||||||
import androidx.car.app.navigation.model.LaneDirection;
|
import androidx.car.app.navigation.model.LaneDirection;
|
||||||
import androidx.car.app.navigation.model.Maneuver;
|
import androidx.car.app.navigation.model.Maneuver;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.sdk.routing.CarDirection;
|
import app.organicmaps.sdk.routing.CarDirection;
|
||||||
import app.organicmaps.sdk.routing.LaneWay;
|
import app.organicmaps.sdk.routing.LaneWay;
|
||||||
|
|
||||||
@@ -26,30 +25,32 @@ public final class RoutingHelpers
|
|||||||
default -> Distance.UNIT_METERS;
|
default -> Distance.UNIT_METERS;
|
||||||
};
|
};
|
||||||
|
|
||||||
return Distance.create(distance.mDistance, displayUnit);
|
return Distance.create(distance.mDistance, displayUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static LaneDirection createLaneDirection(@NonNull LaneWay laneWay, boolean isRecommended)
|
public static LaneDirection createLaneDirection(@NonNull LaneWay laneWay, boolean isRecommended)
|
||||||
{
|
{
|
||||||
int shape = LaneDirection.SHAPE_UNKNOWN;
|
int shape = LaneDirection.SHAPE_UNKNOWN;
|
||||||
shape = switch (laneWay) {
|
shape = switch (laneWay)
|
||||||
case REVERSE -> LaneDirection.SHAPE_U_TURN_LEFT;
|
{
|
||||||
case SHARP_LEFT -> LaneDirection.SHAPE_SHARP_LEFT;
|
case REVERSE -> LaneDirection.SHAPE_U_TURN_LEFT;
|
||||||
case LEFT -> LaneDirection.SHAPE_NORMAL_LEFT;
|
case SHARP_LEFT -> LaneDirection.SHAPE_SHARP_LEFT;
|
||||||
case SLIGHT_LEFT, MERGE_TO_LEFT -> LaneDirection.SHAPE_SLIGHT_LEFT;
|
case LEFT -> LaneDirection.SHAPE_NORMAL_LEFT;
|
||||||
case SLIGHT_RIGHT, MERGE_TO_RIGHT -> LaneDirection.SHAPE_SLIGHT_RIGHT;
|
case SLIGHT_LEFT, MERGE_TO_LEFT -> LaneDirection.SHAPE_SLIGHT_LEFT;
|
||||||
case THROUGH -> LaneDirection.SHAPE_STRAIGHT;
|
case SLIGHT_RIGHT, MERGE_TO_RIGHT -> LaneDirection.SHAPE_SLIGHT_RIGHT;
|
||||||
case RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT;
|
case THROUGH -> LaneDirection.SHAPE_STRAIGHT;
|
||||||
case SHARP_RIGHT -> LaneDirection.SHAPE_SHARP_RIGHT;
|
case RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT;
|
||||||
default -> shape;
|
case SHARP_RIGHT -> LaneDirection.SHAPE_SHARP_RIGHT;
|
||||||
};
|
default -> shape;
|
||||||
|
};
|
||||||
|
|
||||||
return LaneDirection.create(shape, isRecommended);
|
return LaneDirection.create(shape, isRecommended);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Maneuver createManeuver(@NonNull final CarContext context, @NonNull CarDirection carDirection, int roundaboutExitNum)
|
public static Maneuver createManeuver(@NonNull final CarContext context, @NonNull CarDirection carDirection,
|
||||||
|
int roundaboutExitNum)
|
||||||
{
|
{
|
||||||
int maneuverType = switch (carDirection)
|
int maneuverType = switch (carDirection)
|
||||||
{
|
{
|
||||||
@@ -63,14 +64,13 @@ public final class RoutingHelpers
|
|||||||
case U_TURN_LEFT -> Maneuver.TYPE_U_TURN_LEFT;
|
case U_TURN_LEFT -> Maneuver.TYPE_U_TURN_LEFT;
|
||||||
case U_TURN_RIGHT -> Maneuver.TYPE_U_TURN_RIGHT;
|
case U_TURN_RIGHT -> Maneuver.TYPE_U_TURN_RIGHT;
|
||||||
// TODO (AndrewShkrob): add support for CW (clockwise) directions
|
// TODO (AndrewShkrob): add support for CW (clockwise) directions
|
||||||
case ENTER_ROUND_ABOUT, STAY_ON_ROUND_ABOUT, LEAVE_ROUND_ABOUT ->
|
case ENTER_ROUND_ABOUT, STAY_ON_ROUND_ABOUT, LEAVE_ROUND_ABOUT -> Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW;
|
||||||
Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW;
|
|
||||||
case START_AT_THE_END_OF_STREET -> Maneuver.TYPE_DEPART;
|
case START_AT_THE_END_OF_STREET -> Maneuver.TYPE_DEPART;
|
||||||
case REACHED_YOUR_DESTINATION -> Maneuver.TYPE_DESTINATION;
|
case REACHED_YOUR_DESTINATION -> Maneuver.TYPE_DESTINATION;
|
||||||
case EXIT_HIGHWAY_TO_LEFT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT;
|
case EXIT_HIGHWAY_TO_LEFT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT;
|
||||||
case EXIT_HIGHWAY_TO_RIGHT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT;
|
case EXIT_HIGHWAY_TO_RIGHT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT;
|
||||||
};
|
};
|
||||||
final Maneuver.Builder builder = new Maneuver.Builder(maneuverType);
|
final Maneuver.Builder builder = new Maneuver.Builder(maneuverType);
|
||||||
if (maneuverType == Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW)
|
if (maneuverType == Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW)
|
||||||
builder.setRoundaboutExitNumber(roundaboutExitNum > 0 ? roundaboutExitNum : 1);
|
builder.setRoundaboutExitNumber(roundaboutExitNum > 0 ? roundaboutExitNum : 1);
|
||||||
builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(context, carDirection.getTurnRes())).build());
|
builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(context, carDirection.getTurnRes())).build());
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package app.organicmaps.car.util;
|
|||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
@@ -13,7 +12,6 @@ import androidx.car.app.navigation.model.Step;
|
|||||||
import androidx.car.app.navigation.model.TravelEstimate;
|
import androidx.car.app.navigation.model.TravelEstimate;
|
||||||
import androidx.car.app.navigation.model.Trip;
|
import androidx.car.app.navigation.model.Trip;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||||
import app.organicmaps.sdk.routing.LaneWay;
|
import app.organicmaps.sdk.routing.LaneWay;
|
||||||
import app.organicmaps.sdk.routing.RoutingInfo;
|
import app.organicmaps.sdk.routing.RoutingInfo;
|
||||||
@@ -21,7 +19,6 @@ import app.organicmaps.sdk.routing.SingleLaneInfo;
|
|||||||
import app.organicmaps.sdk.util.Distance;
|
import app.organicmaps.sdk.util.Distance;
|
||||||
import app.organicmaps.util.Graphics;
|
import app.organicmaps.util.Graphics;
|
||||||
import app.organicmaps.widget.LanesDrawable;
|
import app.organicmaps.widget.LanesDrawable;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -30,7 +27,8 @@ public final class RoutingUtils
|
|||||||
private RoutingUtils() {}
|
private RoutingUtils() {}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Trip createTrip(@NonNull final CarContext context, @Nullable final RoutingInfo info, @Nullable MapObject endPoint)
|
public static Trip createTrip(@NonNull final CarContext context, @Nullable final RoutingInfo info,
|
||||||
|
@Nullable MapObject endPoint)
|
||||||
{
|
{
|
||||||
final Trip.Builder builder = new Trip.Builder();
|
final Trip.Builder builder = new Trip.Builder();
|
||||||
|
|
||||||
@@ -52,7 +50,8 @@ public final class RoutingUtils
|
|||||||
else
|
else
|
||||||
destinationBuilder.setName(" ");
|
destinationBuilder.setName(" ");
|
||||||
|
|
||||||
builder.addDestination(destinationBuilder.build(), createTravelEstimate(info.distToTarget, info.totalTimeInSeconds));
|
builder.addDestination(destinationBuilder.build(),
|
||||||
|
createTravelEstimate(info.distToTarget, info.totalTimeInSeconds));
|
||||||
|
|
||||||
// TODO (AndrewShkrob): Use real distance and time estimates
|
// TODO (AndrewShkrob): Use real distance and time estimates
|
||||||
builder.addStep(createCurrentStep(context, info), createTravelEstimate(info.distToTurn, 0));
|
builder.addStep(createCurrentStep(context, info), createTravelEstimate(info.distToTurn, 0));
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ import androidx.car.app.model.CarIcon;
|
|||||||
import androidx.car.app.suggestion.SuggestionManager;
|
import androidx.car.app.suggestion.SuggestionManager;
|
||||||
import androidx.car.app.suggestion.model.Suggestion;
|
import androidx.car.app.suggestion.model.Suggestion;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.search.SearchRecents;
|
import app.organicmaps.sdk.search.SearchRecents;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -22,11 +20,13 @@ public final class SuggestionsHelpers
|
|||||||
context.getCarService(SuggestionManager.class).updateSuggestions(createSuggestionsList(context));
|
context.getCarService(SuggestionManager.class).updateSuggestions(createSuggestionsList(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Currently utilizing search history entries; potential future addition to include "Home" and "Work" marks once supported.
|
// TODO: Currently utilizing search history entries; potential future addition to include "Home" and "Work" marks once
|
||||||
|
// supported.
|
||||||
@NonNull
|
@NonNull
|
||||||
private static List<Suggestion> createSuggestionsList(@NonNull final CarContext context)
|
private static List<Suggestion> createSuggestionsList(@NonNull final CarContext context)
|
||||||
{
|
{
|
||||||
final CarIcon iconRecent = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_search_recent)).build();
|
final CarIcon iconRecent =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_search_recent)).build();
|
||||||
final List<Suggestion> suggestions = new ArrayList<>();
|
final List<Suggestion> suggestions = new ArrayList<>();
|
||||||
|
|
||||||
SearchRecents.refresh();
|
SearchRecents.refresh();
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ package app.organicmaps.car.util;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.car.app.CarContext;
|
import androidx.car.app.CarContext;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.routing.RoutingController;
|
import app.organicmaps.routing.RoutingController;
|
||||||
import app.organicmaps.sdk.MapStyle;
|
import app.organicmaps.sdk.MapStyle;
|
||||||
@@ -58,7 +56,8 @@ public final class ThemeUtils
|
|||||||
@UiThread
|
@UiThread
|
||||||
public static void update(@NonNull CarContext context, @NonNull ThemeMode oldThemeMode)
|
public static void update(@NonNull CarContext context, @NonNull ThemeMode oldThemeMode)
|
||||||
{
|
{
|
||||||
final ThemeMode newThemeMode = oldThemeMode == ThemeMode.AUTO ? (context.isDarkMode() ? ThemeMode.NIGHT : ThemeMode.LIGHT) : oldThemeMode;
|
final ThemeMode newThemeMode =
|
||||||
|
oldThemeMode == ThemeMode.AUTO ? (context.isDarkMode() ? ThemeMode.NIGHT : ThemeMode.LIGHT) : oldThemeMode;
|
||||||
|
|
||||||
MapStyle newMapStyle;
|
MapStyle newMapStyle;
|
||||||
if (newThemeMode == ThemeMode.NIGHT)
|
if (newThemeMode == ThemeMode.NIGHT)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import androidx.car.app.model.CarIcon;
|
|||||||
import androidx.car.app.model.OnClickListener;
|
import androidx.car.app.model.OnClickListener;
|
||||||
import androidx.car.app.model.Row;
|
import androidx.car.app.model.Row;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
|
|
||||||
public final class Toggle
|
public final class Toggle
|
||||||
@@ -20,7 +19,8 @@ public final class Toggle
|
|||||||
private static final int CHECKBOX_CHECKED_ICON = R.drawable.ic_checkbox_checked;
|
private static final int CHECKBOX_CHECKED_ICON = R.drawable.ic_checkbox_checked;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Row create(@NonNull final CarContext context, @StringRes int title, @NonNull final OnClickListener onClickListener, boolean checked)
|
public static Row create(@NonNull final CarContext context, @StringRes int title,
|
||||||
|
@NonNull final OnClickListener onClickListener, boolean checked)
|
||||||
{
|
{
|
||||||
final Row.Builder row = new Row.Builder();
|
final Row.Builder row = new Row.Builder();
|
||||||
row.setTitle(context.getString(title));
|
row.setTitle(context.getString(title));
|
||||||
@@ -34,16 +34,19 @@ public final class Toggle
|
|||||||
|
|
||||||
@RequiresCarApi(6)
|
@RequiresCarApi(6)
|
||||||
@NonNull
|
@NonNull
|
||||||
private static androidx.car.app.model.Toggle createToggle(@NonNull final OnClickListener onClickListener, boolean checked)
|
private static androidx.car.app.model.Toggle createToggle(@NonNull final OnClickListener onClickListener,
|
||||||
|
boolean checked)
|
||||||
{
|
{
|
||||||
return new androidx.car.app.model.Toggle.Builder((unused) -> onClickListener.onClick()).setChecked(checked).build();
|
return new androidx.car.app.model.Toggle.Builder((unused) -> onClickListener.onClick()).setChecked(checked).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createCheckbox(
|
private static void createCheckbox(@NonNull final Row.Builder row, @NonNull final CarContext context,
|
||||||
@NonNull final Row.Builder row, @NonNull final CarContext context, @NonNull final OnClickListener onClickListener, boolean checked)
|
@NonNull final OnClickListener onClickListener, boolean checked)
|
||||||
{
|
{
|
||||||
row.setOnClickListener(onClickListener);
|
row.setOnClickListener(onClickListener);
|
||||||
row.setImage(new CarIcon.Builder(IconCompat.createWithResource(context, checked ? CHECKBOX_CHECKED_ICON : CHECKBOX_ICON)).build());
|
row.setImage(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(context, checked ? CHECKBOX_CHECKED_ICON : CHECKBOX_ICON))
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Toggle() {}
|
private Toggle() {}
|
||||||
|
|||||||
@@ -13,28 +13,27 @@ import androidx.car.app.model.CarIcon;
|
|||||||
import androidx.car.app.model.Row;
|
import androidx.car.app.model.Row;
|
||||||
import androidx.car.app.navigation.model.MapController;
|
import androidx.car.app.navigation.model.MapController;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
|
||||||
import app.organicmaps.sdk.Map;
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
|
||||||
import app.organicmaps.sdk.bookmarks.data.Metadata;
|
|
||||||
import app.organicmaps.car.SurfaceRenderer;
|
import app.organicmaps.car.SurfaceRenderer;
|
||||||
import app.organicmaps.car.screens.base.BaseMapScreen;
|
import app.organicmaps.car.screens.base.BaseMapScreen;
|
||||||
import app.organicmaps.car.screens.settings.SettingsScreen;
|
import app.organicmaps.car.screens.settings.SettingsScreen;
|
||||||
|
import app.organicmaps.sdk.Map;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.MapObject;
|
||||||
|
import app.organicmaps.sdk.bookmarks.data.Metadata;
|
||||||
import app.organicmaps.sdk.editor.OpeningHours;
|
import app.organicmaps.sdk.editor.OpeningHours;
|
||||||
import app.organicmaps.sdk.editor.data.Timetable;
|
import app.organicmaps.sdk.editor.data.Timetable;
|
||||||
import app.organicmaps.sdk.location.LocationHelper;
|
import app.organicmaps.sdk.location.LocationHelper;
|
||||||
import app.organicmaps.sdk.location.LocationState;
|
import app.organicmaps.sdk.location.LocationState;
|
||||||
import app.organicmaps.sdk.util.LocationUtils;
|
import app.organicmaps.sdk.util.LocationUtils;
|
||||||
import app.organicmaps.util.Utils;
|
import app.organicmaps.util.Utils;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
public final class UiHelpers
|
public final class UiHelpers
|
||||||
{
|
{
|
||||||
@NonNull
|
@NonNull
|
||||||
public static ActionStrip createSettingsActionStrip(@NonNull BaseMapScreen mapScreen, @NonNull SurfaceRenderer surfaceRenderer)
|
public static ActionStrip createSettingsActionStrip(@NonNull BaseMapScreen mapScreen,
|
||||||
|
@NonNull SurfaceRenderer surfaceRenderer)
|
||||||
{
|
{
|
||||||
return new ActionStrip.Builder().addAction(createSettingsAction(mapScreen, surfaceRenderer)).build();
|
return new ActionStrip.Builder().addAction(createSettingsAction(mapScreen, surfaceRenderer)).build();
|
||||||
}
|
}
|
||||||
@@ -48,7 +47,8 @@ public final class UiHelpers
|
|||||||
final Action panAction = new Action.Builder(Action.PAN).build();
|
final Action panAction = new Action.Builder(Action.PAN).build();
|
||||||
final Action location = createLocationButton(context);
|
final Action location = createLocationButton(context);
|
||||||
final Action zoomIn = new Action.Builder().setIcon(iconPlus).setOnClickListener(surfaceRenderer::onZoomIn).build();
|
final Action zoomIn = new Action.Builder().setIcon(iconPlus).setOnClickListener(surfaceRenderer::onZoomIn).build();
|
||||||
final Action zoomOut = new Action.Builder().setIcon(iconMinus).setOnClickListener(surfaceRenderer::onZoomOut).build();
|
final Action zoomOut =
|
||||||
|
new Action.Builder().setIcon(iconMinus).setOnClickListener(surfaceRenderer::onZoomOut).build();
|
||||||
return new ActionStrip.Builder()
|
return new ActionStrip.Builder()
|
||||||
.addAction(panAction)
|
.addAction(panAction)
|
||||||
.addAction(zoomIn)
|
.addAction(zoomIn)
|
||||||
@@ -70,35 +70,42 @@ public final class UiHelpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Action createSettingsActionForResult(@NonNull BaseMapScreen mapScreen, @NonNull SurfaceRenderer surfaceRenderer, @NonNull OnScreenResultListener onScreenResultListener)
|
public static Action createSettingsActionForResult(@NonNull BaseMapScreen mapScreen,
|
||||||
|
@NonNull SurfaceRenderer surfaceRenderer,
|
||||||
|
@NonNull OnScreenResultListener onScreenResultListener)
|
||||||
{
|
{
|
||||||
return createSettingsAction(mapScreen, surfaceRenderer, onScreenResultListener);
|
return createSettingsAction(mapScreen, surfaceRenderer, onScreenResultListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull SurfaceRenderer surfaceRenderer, @Nullable OnScreenResultListener onScreenResultListener)
|
private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull SurfaceRenderer surfaceRenderer,
|
||||||
|
@Nullable OnScreenResultListener onScreenResultListener)
|
||||||
{
|
{
|
||||||
final CarContext context = mapScreen.getCarContext();
|
final CarContext context = mapScreen.getCarContext();
|
||||||
final CarIcon iconSettings = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_settings)).build();
|
final CarIcon iconSettings =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_settings)).build();
|
||||||
|
|
||||||
return new Action.Builder().setIcon(iconSettings).setOnClickListener(() -> {
|
return new Action.Builder()
|
||||||
// Action.onClickListener for the Screen A maybe called even if the Screen B is shown now.
|
.setIcon(iconSettings)
|
||||||
// We need to check it
|
.setOnClickListener(() -> {
|
||||||
// This may happen when we use PopToRootHack:
|
// Action.onClickListener for the Screen A maybe called even if the Screen B is shown now.
|
||||||
// * ScreenManager.popToRoot()
|
// We need to check it
|
||||||
// * The root screen (A) is shown for a while
|
// This may happen when we use PopToRootHack:
|
||||||
// * User clicks on some action
|
// * ScreenManager.popToRoot()
|
||||||
// * ScreenManager.push(new Screen())
|
// * The root screen (A) is shown for a while
|
||||||
// * New screen (B) is displayed now
|
// * User clicks on some action
|
||||||
// * Action.onClickListener is called for action from root screen (A)
|
// * ScreenManager.push(new Screen())
|
||||||
if (mapScreen.getScreenManager().getTop() != mapScreen)
|
// * New screen (B) is displayed now
|
||||||
return;
|
// * Action.onClickListener is called for action from root screen (A)
|
||||||
final Screen settingsScreen = new SettingsScreen(context, surfaceRenderer);
|
if (mapScreen.getScreenManager().getTop() != mapScreen)
|
||||||
if (onScreenResultListener != null)
|
return;
|
||||||
mapScreen.getScreenManager().pushForResult(settingsScreen, onScreenResultListener);
|
final Screen settingsScreen = new SettingsScreen(context, surfaceRenderer);
|
||||||
else
|
if (onScreenResultListener != null)
|
||||||
mapScreen.getScreenManager().push(settingsScreen);
|
mapScreen.getScreenManager().pushForResult(settingsScreen, onScreenResultListener);
|
||||||
}).build();
|
else
|
||||||
|
mapScreen.getScreenManager().push(settingsScreen);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -112,7 +119,8 @@ public final class UiHelpers
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
final Row.Builder builder = new Row.Builder();
|
final Row.Builder builder = new Row.Builder();
|
||||||
builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_operating_hours)).build());
|
builder.setImage(
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_operating_hours)).build());
|
||||||
|
|
||||||
if (isEmptyTT)
|
if (isEmptyTT)
|
||||||
builder.setTitle(ohStr);
|
builder.setTitle(ohStr);
|
||||||
@@ -159,25 +167,28 @@ public final class UiHelpers
|
|||||||
final int locationMode = Map.isEngineCreated() ? LocationState.getMode() : LocationState.NOT_FOLLOW_NO_POSITION;
|
final int locationMode = Map.isEngineCreated() ? LocationState.getMode() : LocationState.NOT_FOLLOW_NO_POSITION;
|
||||||
CarColor tintColor = Colors.DEFAULT;
|
CarColor tintColor = Colors.DEFAULT;
|
||||||
|
|
||||||
@DrawableRes int drawableRes;
|
@DrawableRes
|
||||||
|
int drawableRes;
|
||||||
switch (locationMode)
|
switch (locationMode)
|
||||||
{
|
{
|
||||||
case LocationState.PENDING_POSITION, LocationState.NOT_FOLLOW_NO_POSITION -> drawableRes = R.drawable.ic_location_off;
|
case LocationState.PENDING_POSITION, LocationState.NOT_FOLLOW_NO_POSITION ->
|
||||||
case LocationState.NOT_FOLLOW -> drawableRes = R.drawable.ic_not_follow;
|
drawableRes = R.drawable.ic_location_off;
|
||||||
case LocationState.FOLLOW ->
|
case LocationState.NOT_FOLLOW -> drawableRes = R.drawable.ic_not_follow;
|
||||||
{
|
case LocationState.FOLLOW ->
|
||||||
drawableRes = R.drawable.ic_follow;
|
{
|
||||||
tintColor = Colors.LOCATION_TINT;
|
drawableRes = R.drawable.ic_follow;
|
||||||
}
|
tintColor = Colors.LOCATION_TINT;
|
||||||
case LocationState.FOLLOW_AND_ROTATE ->
|
}
|
||||||
{
|
case LocationState.FOLLOW_AND_ROTATE ->
|
||||||
drawableRes = R.drawable.ic_follow_and_rotate;
|
{
|
||||||
tintColor = Colors.LOCATION_TINT;
|
drawableRes = R.drawable.ic_follow_and_rotate;
|
||||||
}
|
tintColor = Colors.LOCATION_TINT;
|
||||||
default -> throw new IllegalArgumentException("Invalid button mode: " + locationMode);
|
}
|
||||||
|
default -> throw new IllegalArgumentException("Invalid button mode: " + locationMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
final CarIcon icon = new CarIcon.Builder(IconCompat.createWithResource(context, drawableRes)).setTint(tintColor).build();
|
final CarIcon icon =
|
||||||
|
new CarIcon.Builder(IconCompat.createWithResource(context, drawableRes)).setTint(tintColor).build();
|
||||||
builder.setIcon(icon);
|
builder.setIcon(icon);
|
||||||
builder.setOnClickListener(() -> {
|
builder.setOnClickListener(() -> {
|
||||||
LocationState.nativeSwitchToNextMode();
|
LocationState.nativeSwitchToNextMode();
|
||||||
|
|||||||
@@ -3,5 +3,4 @@ package app.organicmaps.car.util;
|
|||||||
/// Marker interface for screens that require user action to proceed.
|
/// Marker interface for screens that require user action to proceed.
|
||||||
/// These screens can't be dropped from AA's screen stack.
|
/// These screens can't be dropped from AA's screen stack.
|
||||||
public interface UserActionRequired
|
public interface UserActionRequired
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,21 +10,19 @@ import android.text.TextUtils;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
|
||||||
import com.google.android.material.textfield.TextInputEditText;
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmDialogFragment;
|
import app.organicmaps.base.BaseMwmDialogFragment;
|
||||||
import app.organicmaps.util.InputUtils;
|
|
||||||
import app.organicmaps.sdk.util.StringUtils;
|
import app.organicmaps.sdk.util.StringUtils;
|
||||||
|
import app.organicmaps.util.InputUtils;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
|
||||||
public class EditTextDialogFragment extends BaseMwmDialogFragment
|
public class EditTextDialogFragment extends BaseMwmDialogFragment
|
||||||
{
|
{
|
||||||
@@ -60,22 +58,22 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText,
|
public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText,
|
||||||
@Nullable String positiveBtn, @Nullable String negativeBtn,
|
@Nullable String positiveBtn, @Nullable String negativeBtn,
|
||||||
@NonNull Fragment parent, @Nullable Validator inputValidator)
|
@NonNull Fragment parent, @Nullable Validator inputValidator)
|
||||||
{
|
{
|
||||||
return show(title, initialText, "", positiveBtn, negativeBtn, NO_LIMITED_TEXT_LENGTH, parent, inputValidator);
|
return show(title, initialText, "", positiveBtn, negativeBtn, NO_LIMITED_TEXT_LENGTH, parent, inputValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText, @Nullable String hint,
|
public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText, @Nullable String hint,
|
||||||
@Nullable String positiveBtn, @Nullable String negativeBtn,
|
@Nullable String positiveBtn, @Nullable String negativeBtn,
|
||||||
@NonNull Fragment parent, @Nullable Validator inputValidator)
|
@NonNull Fragment parent, @Nullable Validator inputValidator)
|
||||||
{
|
{
|
||||||
return show(title, initialText, hint, positiveBtn, negativeBtn, NO_LIMITED_TEXT_LENGTH, parent, inputValidator);
|
return show(title, initialText, hint, positiveBtn, negativeBtn, NO_LIMITED_TEXT_LENGTH, parent, inputValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText, @Nullable String hint,
|
public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText, @Nullable String hint,
|
||||||
@Nullable String positiveBtn, @Nullable String negativeBtn, int textLimit,
|
@Nullable String positiveBtn, @Nullable String negativeBtn, int textLimit,
|
||||||
@NonNull Fragment parent, @Nullable Validator inputValidator)
|
@NonNull Fragment parent, @Nullable Validator inputValidator)
|
||||||
{
|
{
|
||||||
final Bundle args = new Bundle();
|
final Bundle args = new Bundle();
|
||||||
args.putString(ARG_TITLE, title);
|
args.putString(ARG_TITLE, title);
|
||||||
@@ -85,8 +83,8 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
|
|||||||
args.putString(ARG_HINT, hint);
|
args.putString(ARG_HINT, hint);
|
||||||
args.putInt(ARG_TEXT_LENGTH_LIMIT, textLimit);
|
args.putInt(ARG_TEXT_LENGTH_LIMIT, textLimit);
|
||||||
FragmentManager fragmentManager = parent.getChildFragmentManager();
|
FragmentManager fragmentManager = parent.getChildFragmentManager();
|
||||||
final EditTextDialogFragment fragment = (EditTextDialogFragment) fragmentManager.getFragmentFactory()
|
final EditTextDialogFragment fragment = (EditTextDialogFragment) fragmentManager.getFragmentFactory().instantiate(
|
||||||
.instantiate(parent.requireActivity().getClassLoader(), EditTextDialogFragment.class.getName());
|
parent.requireActivity().getClassLoader(), EditTextDialogFragment.class.getName());
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
fragment.show(fragmentManager, EditTextDialogFragment.class.getName());
|
fragment.show(fragmentManager, EditTextDialogFragment.class.getName());
|
||||||
fragment.mInputValidator = inputValidator;
|
fragment.mInputValidator = inputValidator;
|
||||||
@@ -117,13 +115,15 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
AlertDialog editTextDialog = new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
AlertDialog editTextDialog = new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
||||||
.setView(buildView())
|
.setView(buildView())
|
||||||
.setNegativeButton(negativeButtonText, null)
|
.setNegativeButton(negativeButtonText, null)
|
||||||
.setPositiveButton(positiveButtonText, (dialog, which) -> {
|
.setPositiveButton(positiveButtonText,
|
||||||
final String result = mEtInput.getText().toString();
|
(dialog, which) -> {
|
||||||
processInput(result);
|
final String result = mEtInput.getText().toString();
|
||||||
dismiss();
|
processInput(result);
|
||||||
}).create();
|
dismiss();
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
|
||||||
// Wait till alert is shown to get mPositiveButton.
|
// Wait till alert is shown to get mPositiveButton.
|
||||||
editTextDialog.setOnShowListener((dialog) -> {
|
editTextDialog.setOnShowListener((dialog) -> {
|
||||||
@@ -135,8 +135,7 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Setup validation on input edit.
|
// Setup validation on input edit.
|
||||||
mEtInput.addTextChangedListener(new StringUtils.SimpleTextWatcher()
|
mEtInput.addTextChangedListener(new StringUtils.SimpleTextWatcher() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
public void onTextChanged(CharSequence s, int start, int before, int count)
|
||||||
{
|
{
|
||||||
@@ -173,7 +172,8 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
|
|||||||
|
|
||||||
private View buildView()
|
private View buildView()
|
||||||
{
|
{
|
||||||
@SuppressLint("InflateParams") final View root = requireActivity().getLayoutInflater().inflate(R.layout.dialog_edit_text, null);
|
@SuppressLint("InflateParams")
|
||||||
|
final View root = requireActivity().getLayoutInflater().inflate(R.layout.dialog_edit_text, null);
|
||||||
mEtInputLayout = root.findViewById(R.id.et__input_layout);
|
mEtInputLayout = root.findViewById(R.id.et__input_layout);
|
||||||
mEtInput = mEtInputLayout.findViewById(R.id.et__input);
|
mEtInput = mEtInputLayout.findViewById(R.id.et__input);
|
||||||
mEtInput.setHint(TextUtils.isEmpty(mHint) ? getString(R.string.name) : mHint);
|
mEtInput.setHint(TextUtils.isEmpty(mHint) ? getString(R.string.name) : mHint);
|
||||||
|
|||||||
@@ -2,21 +2,18 @@ package app.organicmaps.downloader;
|
|||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import app.organicmaps.R;
|
||||||
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
|
||||||
|
|
||||||
// Fix missing root certificates for HTTPS connections on Android 7 and below:
|
// Fix missing root certificates for HTTPS connections on Android 7 and below:
|
||||||
// https://community.letsencrypt.org/t/letsencrypt-certificates-fails-on-android-phones-running-android-7-or-older/205686
|
// https://community.letsencrypt.org/t/letsencrypt-certificates-fails-on-android-phones-running-android-7-or-older/205686
|
||||||
@TargetApi(24)
|
@TargetApi(24)
|
||||||
@@ -27,7 +24,8 @@ public class Android7RootCertificateWorkaround
|
|||||||
@TargetApi(24)
|
@TargetApi(24)
|
||||||
private static SSLSocketFactory mSslSocketFactory;
|
private static SSLSocketFactory mSslSocketFactory;
|
||||||
|
|
||||||
public static void applyFixIfNeeded(HttpURLConnection connection) {
|
public static void applyFixIfNeeded(HttpURLConnection connection)
|
||||||
|
{
|
||||||
// Deliberately not checking for null to have an exception from setSSLSocketFactory.
|
// Deliberately not checking for null to have an exception from setSSLSocketFactory.
|
||||||
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.N
|
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.N
|
||||||
&& connection.getURL().getProtocol().equals("https"))
|
&& connection.getURL().getProtocol().equals("https"))
|
||||||
@@ -39,8 +37,8 @@ public class Android7RootCertificateWorkaround
|
|||||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.N)
|
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.N)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
final int[] certificates = new int[]{
|
final int[] certificates = new int[] {R.raw.isrgrootx1, R.raw.globalsignr4, R.raw.gtsrootr1,
|
||||||
R.raw.isrgrootx1, R.raw.globalsignr4, R.raw.gtsrootr1, R.raw.gtsrootr2, R.raw.gtsrootr3, R.raw.gtsrootr4};
|
R.raw.gtsrootr2, R.raw.gtsrootr3, R.raw.gtsrootr4};
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,18 +10,14 @@ import static app.organicmaps.sdk.downloader.CountryItem.STATUS_PROGRESS;
|
|||||||
import static app.organicmaps.sdk.downloader.CountryItem.STATUS_UPDATABLE;
|
import static app.organicmaps.sdk.downloader.CountryItem.STATUS_UPDATABLE;
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.google.android.material.button.MaterialButton;
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
|
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
import app.organicmaps.sdk.downloader.MapManager;
|
import app.organicmaps.sdk.downloader.MapManager;
|
||||||
import app.organicmaps.sdk.downloader.UpdateInfo;
|
import app.organicmaps.sdk.downloader.UpdateInfo;
|
||||||
import app.organicmaps.sdk.util.StringUtils;
|
import app.organicmaps.sdk.util.StringUtils;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
import com.google.android.material.button.MaterialButton;
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
class BottomPanel
|
class BottomPanel
|
||||||
{
|
{
|
||||||
@@ -29,8 +25,7 @@ class BottomPanel
|
|||||||
private final FloatingActionButton mFab;
|
private final FloatingActionButton mFab;
|
||||||
private final MaterialButton mButton;
|
private final MaterialButton mButton;
|
||||||
|
|
||||||
private final View.OnClickListener mDownloadListener = new View.OnClickListener()
|
private final View.OnClickListener mDownloadListener = new View.OnClickListener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v)
|
public void onClick(View v)
|
||||||
{
|
{
|
||||||
@@ -38,8 +33,7 @@ class BottomPanel
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final View.OnClickListener mUpdateListener = new View.OnClickListener()
|
private final View.OnClickListener mUpdateListener = new View.OnClickListener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v)
|
public void onClick(View v)
|
||||||
{
|
{
|
||||||
@@ -48,8 +42,7 @@ class BottomPanel
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final View.OnClickListener mCancelListener = new View.OnClickListener()
|
private final View.OnClickListener mCancelListener = new View.OnClickListener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v)
|
public void onClick(View v)
|
||||||
{
|
{
|
||||||
@@ -58,8 +51,7 @@ class BottomPanel
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final View.OnClickListener mRetryListener = new View.OnClickListener()
|
private final View.OnClickListener mRetryListener = new View.OnClickListener() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v)
|
public void onClick(View v)
|
||||||
{
|
{
|
||||||
@@ -73,7 +65,7 @@ class BottomPanel
|
|||||||
|
|
||||||
mFab = frame.findViewById(R.id.fab);
|
mFab = frame.findViewById(R.id.fab);
|
||||||
mFab.setOnClickListener(v -> {
|
mFab.setOnClickListener(v -> {
|
||||||
if (mFragment.getAdapter() != null )
|
if (mFragment.getAdapter() != null)
|
||||||
mFragment.getAdapter().setAvailableMapsMode();
|
mFragment.getAdapter().setAvailableMapsMode();
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
@@ -83,8 +75,9 @@ class BottomPanel
|
|||||||
|
|
||||||
private void setUpdateAllState(UpdateInfo info)
|
private void setUpdateAllState(UpdateInfo info)
|
||||||
{
|
{
|
||||||
mButton.setText(StringUtils.formatUsingUsLocale("%s (%s)", mFragment.getString(R.string.downloader_update_all_button),
|
mButton.setText(
|
||||||
StringUtils.getFileSizeString(mFragment.requireContext(), info.totalSize)));
|
StringUtils.formatUsingUsLocale("%s (%s)", mFragment.getString(R.string.downloader_update_all_button),
|
||||||
|
StringUtils.getFileSizeString(mFragment.requireContext(), info.totalSize)));
|
||||||
mButton.setOnClickListener(mUpdateListener);
|
mButton.setOnClickListener(mUpdateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +119,7 @@ class BottomPanel
|
|||||||
{
|
{
|
||||||
UpdateInfo info = MapManager.nativeGetUpdateInfo(root);
|
UpdateInfo info = MapManager.nativeGetUpdateInfo(root);
|
||||||
setUpdateAllState(info);
|
setUpdateAllState(info);
|
||||||
} // Special case for "Countries" node when no maps currently downloaded.
|
} // Special case for "Countries" node when no maps currently downloaded.
|
||||||
case STATUS_DOWNLOADABLE, STATUS_DONE, STATUS_PARTLY -> show = false;
|
case STATUS_DOWNLOADABLE, STATUS_DONE, STATUS_PARTLY -> show = false;
|
||||||
case STATUS_PROGRESS, STATUS_APPLYING, STATUS_ENQUEUED -> setCancelState();
|
case STATUS_PROGRESS, STATUS_APPLYING, STATUS_ENQUEUED -> setCancelState();
|
||||||
case STATUS_FAILED -> setRetryFailedStates();
|
case STATUS_FAILED -> setRetryFailedStates();
|
||||||
|
|||||||
@@ -7,23 +7,19 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
import com.google.android.material.button.MaterialButton;
|
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmFragment;
|
import app.organicmaps.base.BaseMwmFragment;
|
||||||
import app.organicmaps.base.BaseMwmFragmentActivity;
|
import app.organicmaps.base.BaseMwmFragmentActivity;
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
import app.organicmaps.sdk.downloader.MapManager;
|
import app.organicmaps.sdk.downloader.MapManager;
|
||||||
import app.organicmaps.widget.WheelProgressView;
|
|
||||||
import app.organicmaps.sdk.util.StringUtils;
|
import app.organicmaps.sdk.util.StringUtils;
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
import app.organicmaps.widget.WheelProgressView;
|
||||||
|
import com.google.android.material.button.MaterialButton;
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CountrySuggestFragment extends BaseMwmFragment implements View.OnClickListener
|
public class CountrySuggestFragment extends BaseMwmFragment implements View.OnClickListener
|
||||||
@@ -55,8 +51,7 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
initViews(view);
|
initViews(view);
|
||||||
mListenerSlot = MapManager.nativeSubscribe(new MapManager.StorageCallback()
|
mListenerSlot = MapManager.nativeSubscribe(new MapManager.StorageCallback() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||||
{
|
{
|
||||||
@@ -75,13 +70,9 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl
|
|||||||
|
|
||||||
switch (item.newStatus)
|
switch (item.newStatus)
|
||||||
{
|
{
|
||||||
case CountryItem.STATUS_FAILED:
|
case CountryItem.STATUS_FAILED: updateViews(); return;
|
||||||
updateViews();
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CountryItem.STATUS_DONE:
|
case CountryItem.STATUS_DONE: exitFragment(); return;
|
||||||
exitFragment();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -140,9 +131,9 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl
|
|||||||
if (mCurrentCountry == null || !isAdded())
|
if (mCurrentCountry == null || !isAdded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mBtnDownloadMap.setText(StringUtils.formatUsingUsLocale("%1$s (%2$s)",
|
mBtnDownloadMap.setText(
|
||||||
getString(R.string.downloader_download_map),
|
StringUtils.formatUsingUsLocale("%1$s (%2$s)", getString(R.string.downloader_download_map),
|
||||||
StringUtils.getFileSizeString(requireContext(), mCurrentCountry.totalSize)));
|
StringUtils.getFileSizeString(requireContext(), mCurrentCountry.totalSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initViews(View view)
|
private void initViews(View view)
|
||||||
@@ -195,7 +186,8 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl
|
|||||||
|
|
||||||
private void updateProgress()
|
private void updateProgress()
|
||||||
{
|
{
|
||||||
String text = getString(R.string.downloader_downloading) + " " + StringUtils.formatPercent(mDownloadingCountry.progress / 100);
|
String text = getString(R.string.downloader_downloading) + " "
|
||||||
|
+ StringUtils.formatPercent(mDownloadingCountry.progress / 100);
|
||||||
mTvProgress.setText(text);
|
mTvProgress.setText(text);
|
||||||
mWpvDownloadProgress.setProgress(Math.round(mDownloadingCountry.progress));
|
mWpvDownloadProgress.setProgress(Math.round(mDownloadingCountry.progress));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.organicmaps.downloader;
|
package app.organicmaps.downloader;
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import app.organicmaps.base.BaseMwmFragmentActivity;
|
import app.organicmaps.base.BaseMwmFragmentActivity;
|
||||||
import app.organicmaps.base.OnBackPressListener;
|
import app.organicmaps.base.OnBackPressListener;
|
||||||
|
|
||||||
@@ -18,7 +17,8 @@ public class DownloaderActivity extends BaseMwmFragmentActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onBackPressed()
|
public void onBackPressed()
|
||||||
{
|
{
|
||||||
OnBackPressListener fragment = (OnBackPressListener)getSupportFragmentManager().findFragmentById(getFragmentContentResId());
|
OnBackPressListener fragment =
|
||||||
|
(OnBackPressListener) getSupportFragmentManager().findFragmentById(getFragmentContentResId());
|
||||||
if (!fragment.onBackPressed())
|
if (!fragment.onBackPressed())
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,11 @@ import android.text.style.StyleSpan;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.LayoutRes;
|
import androidx.annotation.LayoutRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import app.organicmaps.MwmActivity;
|
import app.organicmaps.MwmActivity;
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
@@ -30,7 +28,6 @@ import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
|
|||||||
import app.organicmaps.util.bottomsheet.MenuBottomSheetItem;
|
import app.organicmaps.util.bottomsheet.MenuBottomSheetItem;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -60,7 +57,8 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
// Use List, because we have multiple search results now for a single country.
|
// Use List, because we have multiple search results now for a single country.
|
||||||
private final Map<String, List<CountryItem>> mCountryIndex = new HashMap<>();
|
private final Map<String, List<CountryItem>> mCountryIndex = new HashMap<>();
|
||||||
|
|
||||||
private final Stack<PathEntry> mPath = new Stack<>(); // Holds navigation history. The last element is the current level.
|
private final Stack<PathEntry> mPath =
|
||||||
|
new Stack<>(); // Holds navigation history. The last element is the current level.
|
||||||
|
|
||||||
private int mListenerSlot;
|
private int mListenerSlot;
|
||||||
private CountryItem mSelectedItem;
|
private CountryItem mSelectedItem;
|
||||||
@@ -156,20 +154,16 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
}
|
}
|
||||||
|
|
||||||
private record PathEntry(CountryItem item, boolean myMapsMode, int topPosition, int topOffset)
|
private record PathEntry(CountryItem item, boolean myMapsMode, int topPosition, int topOffset)
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return item.id + " (" + item.name + "), " +
|
|
||||||
"myMapsMode: " + myMapsMode +
|
|
||||||
", topPosition: " + topPosition +
|
|
||||||
", topOffset: " + topOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback()
|
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return item.id + " (" + item.name + "), "
|
||||||
|
+ "myMapsMode: " + myMapsMode + ", topPosition: " + topPosition + ", topOffset: " + topOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() {
|
||||||
private void updateItem(String countryId)
|
private void updateItem(String countryId)
|
||||||
{
|
{
|
||||||
List<CountryItem> lst = mCountryIndex.get(countryId);
|
List<CountryItem> lst = mCountryIndex.get(countryId);
|
||||||
@@ -226,7 +220,6 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
return inflate(parent, R.layout.downloader_item);
|
return inflate(parent, R.layout.downloader_item);
|
||||||
else
|
else
|
||||||
return inflate(parent, R.layout.downloader_item_header);
|
return inflate(parent, R.layout.downloader_item_header);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolderWrapper extends RecyclerView.ViewHolder
|
class ViewHolderWrapper extends RecyclerView.ViewHolder
|
||||||
@@ -276,7 +269,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
{
|
{
|
||||||
mSelectedItem = selectedItem;
|
mSelectedItem = selectedItem;
|
||||||
MenuBottomSheetFragment.newInstance(DOWNLOADER_MENU_ID, mSelectedItem.name)
|
MenuBottomSheetFragment.newInstance(DOWNLOADER_MENU_ID, mSelectedItem.name)
|
||||||
.show(mFragment.getChildFragmentManager(), DOWNLOADER_MENU_ID);
|
.show(mFragment.getChildFragmentManager(), DOWNLOADER_MENU_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<MenuBottomSheetItem> getMenuItems()
|
public ArrayList<MenuBottomSheetItem> getMenuItems()
|
||||||
@@ -284,9 +277,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
|
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
|
||||||
switch (mSelectedItem.status)
|
switch (mSelectedItem.status)
|
||||||
{
|
{
|
||||||
case CountryItem.STATUS_DOWNLOADABLE:
|
case CountryItem.STATUS_DOWNLOADABLE: items.add(getDownloadMenuItem()); break;
|
||||||
items.add(getDownloadMenuItem());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CountryItem.STATUS_UPDATABLE:
|
case CountryItem.STATUS_UPDATABLE:
|
||||||
items.add(getUpdateMenuItem());
|
items.add(getUpdateMenuItem());
|
||||||
@@ -325,7 +316,6 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private MenuBottomSheetItem getDownloadMenuItem()
|
private MenuBottomSheetItem getDownloadMenuItem()
|
||||||
{
|
{
|
||||||
return new MenuBottomSheetItem(R.string.downloader_download_map, R.drawable.ic_download,
|
return new MenuBottomSheetItem(R.string.downloader_download_map, R.drawable.ic_download,
|
||||||
@@ -357,8 +347,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
|
|
||||||
private MenuBottomSheetItem getCancelMenuItem()
|
private MenuBottomSheetItem getCancelMenuItem()
|
||||||
{
|
{
|
||||||
return new MenuBottomSheetItem(R.string.cancel, R.drawable.ic_cancel,
|
return new MenuBottomSheetItem(R.string.cancel, R.drawable.ic_cancel, () -> onCancelActionSelected(mSelectedItem));
|
||||||
() -> onCancelActionSelected(mSelectedItem));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ItemViewHolder extends BaseInnerViewHolder<CountryItem>
|
private class ItemViewHolder extends BaseInnerViewHolder<CountryItem>
|
||||||
@@ -373,8 +362,9 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
{
|
{
|
||||||
switch (mItem.status)
|
switch (mItem.status)
|
||||||
{
|
{
|
||||||
case CountryItem.STATUS_DONE, CountryItem.STATUS_PROGRESS, CountryItem.STATUS_APPLYING, CountryItem.STATUS_ENQUEUED ->
|
case CountryItem.STATUS_DONE, CountryItem.STATUS_PROGRESS, CountryItem.STATUS_APPLYING,
|
||||||
processLongClick();
|
CountryItem.STATUS_ENQUEUED ->
|
||||||
|
processLongClick();
|
||||||
case CountryItem.STATUS_DOWNLOADABLE, CountryItem.STATUS_PARTLY ->
|
case CountryItem.STATUS_DOWNLOADABLE, CountryItem.STATUS_PARTLY ->
|
||||||
{
|
{
|
||||||
if (clickOnStatus)
|
if (clickOnStatus)
|
||||||
@@ -384,7 +374,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
}
|
}
|
||||||
case CountryItem.STATUS_FAILED -> MapManager.warn3gAndRetry(mActivity, mItem.id, null);
|
case CountryItem.STATUS_FAILED -> MapManager.warn3gAndRetry(mActivity, mItem.id, null);
|
||||||
case CountryItem.STATUS_UPDATABLE ->
|
case CountryItem.STATUS_UPDATABLE ->
|
||||||
MapManager.warnOn3gUpdate(mActivity, mItem.id, () -> MapManager.startUpdate(mItem.id));
|
MapManager.warnOn3gUpdate(mActivity, mItem.id, () -> MapManager.startUpdate(mItem.id));
|
||||||
default -> throw new IllegalArgumentException("Inappropriate item status: " + mItem.status);
|
default -> throw new IllegalArgumentException("Inappropriate item status: " + mItem.status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,15 +386,13 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
|
|
||||||
ItemViewHolder(View frame)
|
ItemViewHolder(View frame)
|
||||||
{
|
{
|
||||||
mStatusIcon = new DownloaderStatusIcon(frame.findViewById(R.id.downloader_status_frame))
|
mStatusIcon = new DownloaderStatusIcon(frame.findViewById(R.id.downloader_status_frame)) {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
protected int selectIcon(CountryItem country)
|
protected int selectIcon(CountryItem country)
|
||||||
{
|
{
|
||||||
if (country.status == CountryItem.STATUS_DOWNLOADABLE || country.status == CountryItem.STATUS_PARTLY)
|
if (country.status == CountryItem.STATUS_DOWNLOADABLE || country.status == CountryItem.STATUS_PARTLY)
|
||||||
{
|
{
|
||||||
return (country.isExpandable() ? (mMyMapsMode ? R.attr.status_folder_done
|
return (country.isExpandable() ? (mMyMapsMode ? R.attr.status_folder_done : R.attr.status_folder)
|
||||||
: R.attr.status_folder)
|
|
||||||
: R.attr.status_downloadable);
|
: R.attr.status_downloadable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,9 +463,10 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
|
|
||||||
if (mItem.isExpandable())
|
if (mItem.isExpandable())
|
||||||
{
|
{
|
||||||
UiUtils.setTextAndHideIfEmpty(mSubtitle, String.format("%s: %s", mActivity.getString(R.string.downloader_status_maps),
|
UiUtils.setTextAndHideIfEmpty(
|
||||||
mActivity.getString(R.string.downloader_of, mItem.childCount,
|
mSubtitle,
|
||||||
mItem.totalChildCount)));
|
String.format("%s: %s", mActivity.getString(R.string.downloader_status_maps),
|
||||||
|
mActivity.getString(R.string.downloader_of, mItem.childCount, mItem.totalChildCount)));
|
||||||
}
|
}
|
||||||
|
|
||||||
UiUtils.showIf(mSearchResultsMode && !TextUtils.isEmpty(found), mFoundName);
|
UiUtils.showIf(mSearchResultsMode && !TextUtils.isEmpty(found), mFoundName);
|
||||||
@@ -490,14 +479,12 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
private long getMapDisplaySize()
|
private long getMapDisplaySize()
|
||||||
{
|
{
|
||||||
long size;
|
long size;
|
||||||
if (mItem.status == CountryItem.STATUS_ENQUEUED ||
|
if (mItem.status == CountryItem.STATUS_ENQUEUED || mItem.status == CountryItem.STATUS_PROGRESS
|
||||||
mItem.status == CountryItem.STATUS_PROGRESS ||
|
|| mItem.status == CountryItem.STATUS_APPLYING)
|
||||||
mItem.status == CountryItem.STATUS_APPLYING)
|
|
||||||
{
|
{
|
||||||
size = mItem.enqueuedSize;
|
size = mItem.enqueuedSize;
|
||||||
}
|
}
|
||||||
else if (mItem.status == CountryItem.STATUS_FAILED ||
|
else if (mItem.status == CountryItem.STATUS_FAILED || mItem.status == CountryItem.STATUS_DOWNLOADABLE)
|
||||||
mItem.status == CountryItem.STATUS_DOWNLOADABLE)
|
|
||||||
{
|
{
|
||||||
size = mItem.totalSize;
|
size = mItem.totalSize;
|
||||||
}
|
}
|
||||||
@@ -521,7 +508,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
|
|
||||||
void bind(String text)
|
void bind(String text)
|
||||||
{
|
{
|
||||||
mTitle.setText(text);
|
mTitle.setText(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,7 +518,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
|
|
||||||
int headerId = 0;
|
int headerId = 0;
|
||||||
int prev = -1;
|
int prev = -1;
|
||||||
for (CountryItem ci: mItems)
|
for (CountryItem ci : mItems)
|
||||||
{
|
{
|
||||||
// Disable headers when using the search
|
// Disable headers when using the search
|
||||||
if (!mSearchResultsMode)
|
if (!mSearchResultsMode)
|
||||||
@@ -620,12 +607,13 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
collectHeaders();
|
collectHeaders();
|
||||||
|
|
||||||
mCountryIndex.clear();
|
mCountryIndex.clear();
|
||||||
for (CountryItem ci: mItems)
|
for (CountryItem ci : mItems)
|
||||||
{
|
{
|
||||||
List<CountryItem> lst = mCountryIndex.get(ci.id);
|
List<CountryItem> lst = mCountryIndex.get(ci.id);
|
||||||
if (lst != null)
|
if (lst != null)
|
||||||
lst.add(ci);
|
lst.add(ci);
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
lst = new ArrayList<>();
|
lst = new ArrayList<>();
|
||||||
lst.add(ci);
|
lst.add(ci);
|
||||||
mCountryIndex.put(ci.id, lst);
|
mCountryIndex.put(ci.id, lst);
|
||||||
@@ -682,7 +670,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
|
|
||||||
private void goDeeper(CountryItem child, boolean refresh)
|
private void goDeeper(CountryItem child, boolean refresh)
|
||||||
{
|
{
|
||||||
LinearLayoutManager lm = (LinearLayoutManager)mRecycler.getLayoutManager();
|
LinearLayoutManager lm = (LinearLayoutManager) mRecycler.getLayoutManager();
|
||||||
|
|
||||||
// Save scroll positions (top item + item`s offset) for current hierarchy level
|
// Save scroll positions (top item + item`s offset) for current hierarchy level
|
||||||
int position = lm.findFirstVisibleItemPosition();
|
int position = lm.findFirstVisibleItemPosition();
|
||||||
@@ -748,12 +736,14 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||||||
return (canGoUpwards() ? mPath.peek().item : CountryItem.fill(CountryItem.getRootId()));
|
return (canGoUpwards() ? mPath.peek().item : CountryItem.fill(CountryItem.getRootId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull String getCurrentRootId()
|
@NonNull
|
||||||
|
String getCurrentRootId()
|
||||||
{
|
{
|
||||||
return (canGoUpwards() ? getCurrentRootItem().id : CountryItem.getRootId());
|
return (canGoUpwards() ? getCurrentRootItem().id : CountryItem.getRootId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable String getCurrentRootName()
|
@Nullable
|
||||||
|
String getCurrentRootName()
|
||||||
{
|
{
|
||||||
return (canGoUpwards() ? getCurrentRootItem().name : null);
|
return (canGoUpwards() ? getCurrentRootItem().name : null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
@@ -13,7 +12,6 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.base.BaseMwmRecyclerFragment;
|
import app.organicmaps.base.BaseMwmRecyclerFragment;
|
||||||
import app.organicmaps.base.OnBackPressListener;
|
import app.organicmaps.base.OnBackPressListener;
|
||||||
@@ -21,16 +19,14 @@ import app.organicmaps.sdk.downloader.CountryItem;
|
|||||||
import app.organicmaps.sdk.downloader.MapManager;
|
import app.organicmaps.sdk.downloader.MapManager;
|
||||||
import app.organicmaps.sdk.search.MapSearchListener;
|
import app.organicmaps.sdk.search.MapSearchListener;
|
||||||
import app.organicmaps.sdk.search.SearchEngine;
|
import app.organicmaps.sdk.search.SearchEngine;
|
||||||
import app.organicmaps.widget.PlaceholderView;
|
|
||||||
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
|
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
|
||||||
import app.organicmaps.util.bottomsheet.MenuBottomSheetItem;
|
import app.organicmaps.util.bottomsheet.MenuBottomSheetItem;
|
||||||
|
import app.organicmaps.widget.PlaceholderView;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapter>
|
public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapter>
|
||||||
implements OnBackPressListener,
|
implements OnBackPressListener, MenuBottomSheetFragment.MenuBottomSheetInterface
|
||||||
MenuBottomSheetFragment.MenuBottomSheetInterface
|
|
||||||
{
|
{
|
||||||
private DownloaderToolbarController mToolbarController;
|
private DownloaderToolbarController mToolbarController;
|
||||||
|
|
||||||
@@ -43,7 +39,9 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapte
|
|||||||
|
|
||||||
private int mSubscriberSlot;
|
private int mSubscriberSlot;
|
||||||
|
|
||||||
final ActivityResultLauncher<Intent> startVoiceRecognitionForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> mToolbarController.onVoiceRecognitionResult(activityResult));
|
final ActivityResultLauncher<Intent> startVoiceRecognitionForResult =
|
||||||
|
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
|
||||||
|
activityResult -> mToolbarController.onVoiceRecognitionResult(activityResult));
|
||||||
|
|
||||||
private final RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
|
private final RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -54,8 +52,7 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapte
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final MapSearchListener mSearchListener = new MapSearchListener()
|
private final MapSearchListener mSearchListener = new MapSearchListener() {
|
||||||
{
|
|
||||||
@Keep
|
@Keep
|
||||||
@Override
|
@Override
|
||||||
public void onMapSearchResults(@NonNull Result[] results, long timestamp, boolean isLast)
|
public void onMapSearchResults(@NonNull Result[] results, long timestamp, boolean isLast)
|
||||||
@@ -133,8 +130,7 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapte
|
|||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(view, new DownloaderInsetsListener(view));
|
ViewCompat.setOnApplyWindowInsetsListener(view, new DownloaderInsetsListener(view));
|
||||||
|
|
||||||
mSubscriberSlot = MapManager.nativeSubscribe(new MapManager.StorageCallback()
|
mSubscriberSlot = MapManager.nativeSubscribe(new MapManager.StorageCallback() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||||
{
|
{
|
||||||
@@ -143,7 +139,8 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapte
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProgress(String countryId, long localSize, long remoteSize) {}
|
public void onProgress(String countryId, long localSize, long remoteSize)
|
||||||
|
{}
|
||||||
});
|
});
|
||||||
|
|
||||||
SearchEngine.INSTANCE.addMapListener(mSearchListener);
|
SearchEngine.INSTANCE.addMapListener(mSearchListener);
|
||||||
@@ -214,7 +211,6 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapte
|
|||||||
return mAdapter;
|
return mAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public DownloaderAdapter getAdapter()
|
public DownloaderAdapter getAdapter()
|
||||||
@@ -237,7 +233,8 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment<DownloaderAdapte
|
|||||||
if (mAdapter != null && mAdapter.isSearchResultsMode())
|
if (mAdapter != null && mAdapter.isSearchResultsMode())
|
||||||
placeholder.setContent(R.string.search_not_found, R.string.search_not_found_query);
|
placeholder.setContent(R.string.search_not_found, R.string.search_not_found_query);
|
||||||
else
|
else
|
||||||
placeholder.setContent(R.string.downloader_no_downloaded_maps_title, R.string.downloader_no_downloaded_maps_message);
|
placeholder.setContent(R.string.downloader_no_downloaded_maps_title,
|
||||||
|
R.string.downloader_no_downloaded_maps_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package app.organicmaps.downloader;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.graphics.Insets;
|
import androidx.core.graphics.Insets;
|
||||||
import androidx.core.view.OnApplyWindowInsetsListener;
|
import androidx.core.view.OnApplyWindowInsetsListener;
|
||||||
@@ -15,7 +14,6 @@ import app.organicmaps.util.WindowInsetUtils;
|
|||||||
|
|
||||||
final class DownloaderInsetsListener implements OnApplyWindowInsetsListener
|
final class DownloaderInsetsListener implements OnApplyWindowInsetsListener
|
||||||
{
|
{
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -81,11 +79,8 @@ final class DownloaderInsetsListener implements OnApplyWindowInsetsListener
|
|||||||
{
|
{
|
||||||
int bottomInset = isAnyButtonVisible ? 0 : insets.bottom;
|
int bottomInset = isAnyButtonVisible ? 0 : insets.bottom;
|
||||||
|
|
||||||
mRecyclerView.setPadding(
|
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(),
|
||||||
mRecyclerView.getPaddingLeft(),
|
mRecyclerView.getPaddingRight(), bottomInset);
|
||||||
mRecyclerView.getPaddingTop(),
|
|
||||||
mRecyclerView.getPaddingRight(),
|
|
||||||
bottomInset);
|
|
||||||
|
|
||||||
final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mRecyclerView.getLayoutParams();
|
final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mRecyclerView.getLayoutParams();
|
||||||
layoutParams.rightMargin = insets.right;
|
layoutParams.rightMargin = insets.right;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import android.app.PendingIntent;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
@@ -16,7 +15,6 @@ import androidx.core.app.NotificationChannelCompat;
|
|||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
import androidx.core.app.NotificationManagerCompat;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import app.organicmaps.MwmActivity;
|
import app.organicmaps.MwmActivity;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.downloader.MapManager;
|
import app.organicmaps.sdk.downloader.MapManager;
|
||||||
@@ -41,20 +39,20 @@ public class DownloaderNotifier
|
|||||||
public static void createNotificationChannel(@NonNull Context context)
|
public static void createNotificationChannel(@NonNull Context context)
|
||||||
{
|
{
|
||||||
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||||
final NotificationChannelCompat channel = new NotificationChannelCompat.Builder(CHANNEL_ID,
|
final NotificationChannelCompat channel =
|
||||||
NotificationManagerCompat.IMPORTANCE_LOW)
|
new NotificationChannelCompat.Builder(CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_LOW)
|
||||||
.setName(context.getString(R.string.notification_channel_downloader))
|
.setName(context.getString(R.string.notification_channel_downloader))
|
||||||
.setShowBadge(true)
|
.setShowBadge(true)
|
||||||
.setVibrationEnabled(false)
|
.setVibrationEnabled(false)
|
||||||
.setLightsEnabled(false)
|
.setLightsEnabled(false)
|
||||||
.build();
|
.build();
|
||||||
notificationManager.createNotificationChannel(channel);
|
notificationManager.createNotificationChannel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyDownloadFailed(@Nullable String countryId)
|
public void notifyDownloadFailed(@Nullable String countryId)
|
||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||||
ContextCompat.checkSelfPermission(mContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED)
|
&& ContextCompat.checkSelfPermission(mContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED)
|
||||||
{
|
{
|
||||||
Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification");
|
Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification");
|
||||||
return;
|
return;
|
||||||
@@ -67,37 +65,40 @@ public class DownloaderNotifier
|
|||||||
var contentPendingIntent = getNotificationPendingIntent(countryId);
|
var contentPendingIntent = getNotificationPendingIntent(countryId);
|
||||||
|
|
||||||
final Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID)
|
final Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
||||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
.setSmallIcon(R.drawable.ic_logo_small)
|
.setSmallIcon(R.drawable.ic_logo_small)
|
||||||
.setColor(ContextCompat.getColor(mContext, R.color.notification))
|
.setColor(ContextCompat.getColor(mContext, R.color.notification))
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentText(content)
|
.setContentText(content)
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setTicker(getTicker(mContext, title, content))
|
.setTicker(getTicker(mContext, title, content))
|
||||||
.setContentIntent(contentPendingIntent)
|
.setContentIntent(contentPendingIntent)
|
||||||
.setOnlyAlertOnce(true)
|
.setOnlyAlertOnce(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Logger.i(TAG, "Notifying about failed map download");
|
Logger.i(TAG, "Notifying about failed map download");
|
||||||
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mContext);
|
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mContext);
|
||||||
notificationManager.notify(NOTIFICATION_ID, notification);
|
notificationManager.notify(NOTIFICATION_ID, notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyProgress() {
|
public void notifyProgress()
|
||||||
|
{
|
||||||
notifyProgress(null, 0, 0);
|
notifyProgress(null, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyProgress(@Nullable String countryId, int maxProgress, int progress) {
|
public void notifyProgress(@Nullable String countryId, int maxProgress, int progress)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
{
|
||||||
ContextCompat.checkSelfPermission(mContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||||
|
&& ContextCompat.checkSelfPermission(mContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED)
|
||||||
{
|
{
|
||||||
Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification");
|
Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationManagerCompat.from(mContext).notify(NOTIFICATION_ID, buildProgressNotification(countryId, maxProgress, progress));
|
NotificationManagerCompat.from(mContext).notify(NOTIFICATION_ID,
|
||||||
|
buildProgressNotification(countryId, maxProgress, progress));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -123,17 +124,18 @@ public class DownloaderNotifier
|
|||||||
final String title = mContext.getString(R.string.app_name);
|
final String title = mContext.getString(R.string.app_name);
|
||||||
|
|
||||||
return new NotificationCompat.Builder(mContext, CHANNEL_ID)
|
return new NotificationCompat.Builder(mContext, CHANNEL_ID)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
.setSmallIcon(R.drawable.ic_logo_small)
|
.setSmallIcon(R.drawable.ic_logo_small)
|
||||||
.setColor(ContextCompat.getColor(mContext, R.color.notification))
|
.setColor(ContextCompat.getColor(mContext, R.color.notification))
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentIntent(getNotificationPendingIntent(countryId));
|
.setContentIntent(getNotificationPendingIntent(countryId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private PendingIntent getNotificationPendingIntent(@Nullable String countryId) {
|
private PendingIntent getNotificationPendingIntent(@Nullable String countryId)
|
||||||
|
{
|
||||||
final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE;
|
final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE;
|
||||||
final Intent contentIntent = MwmActivity.createShowMapIntent(mContext, countryId);
|
final Intent contentIntent = MwmActivity.createShowMapIntent(mContext, countryId);
|
||||||
contentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
contentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
@@ -143,8 +145,8 @@ public class DownloaderNotifier
|
|||||||
@NonNull
|
@NonNull
|
||||||
private static CharSequence getTicker(@NonNull Context context, @NonNull String title, @NonNull String content)
|
private static CharSequence getTicker(@NonNull Context context, @NonNull String title, @NonNull String content)
|
||||||
{
|
{
|
||||||
@StringRes final int templateResId = StringUtils.isRtl() ? R.string.notification_ticker_rtl
|
@StringRes
|
||||||
: R.string.notification_ticker_ltr;
|
final int templateResId = StringUtils.isRtl() ? R.string.notification_ticker_rtl : R.string.notification_ticker_ltr;
|
||||||
return context.getString(templateResId, title, content);
|
return context.getString(templateResId, title, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,17 +9,14 @@ import android.content.Intent;
|
|||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.app.ServiceCompat;
|
import androidx.core.app.ServiceCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
import app.organicmaps.sdk.downloader.MapManager;
|
import app.organicmaps.sdk.downloader.MapManager;
|
||||||
import app.organicmaps.sdk.util.log.Logger;
|
import app.organicmaps.sdk.util.log.Logger;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class DownloaderService extends Service implements MapManager.StorageCallback
|
public class DownloaderService extends Service implements MapManager.StorageCallback
|
||||||
{
|
{
|
||||||
@@ -54,8 +51,7 @@ public class DownloaderService extends Service implements MapManager.StorageCall
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof ForegroundServiceStartNotAllowedException)
|
||||||
e instanceof ForegroundServiceStartNotAllowedException)
|
|
||||||
{
|
{
|
||||||
// App not in a valid state to start foreground service (e.g started from bg)
|
// App not in a valid state to start foreground service (e.g started from bg)
|
||||||
Logger.e(TAG, "Not in a valid state to start foreground service", e);
|
Logger.e(TAG, "Not in a valid state to start foreground service", e);
|
||||||
@@ -90,7 +86,8 @@ public class DownloaderService extends Service implements MapManager.StorageCall
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
{
|
{
|
||||||
stopForeground(Service.STOP_FOREGROUND_DETACH);
|
stopForeground(Service.STOP_FOREGROUND_DETACH);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
stopForeground(false);
|
stopForeground(false);
|
||||||
}
|
}
|
||||||
@@ -102,8 +99,8 @@ public class DownloaderService extends Service implements MapManager.StorageCall
|
|||||||
@Override
|
@Override
|
||||||
public void onProgress(String countryId, long localSize, long remoteSize)
|
public void onProgress(String countryId, long localSize, long remoteSize)
|
||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||||
ContextCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED)
|
&& ContextCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED)
|
||||||
{
|
{
|
||||||
Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification");
|
Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -2,17 +2,14 @@ package app.organicmaps.downloader;
|
|||||||
|
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.AttrRes;
|
import androidx.annotation.AttrRes;
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
|
|
||||||
import com.google.android.material.imageview.ShapeableImageView;
|
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.sdk.downloader.CountryItem;
|
import app.organicmaps.sdk.downloader.CountryItem;
|
||||||
import app.organicmaps.widget.WheelProgressView;
|
|
||||||
import app.organicmaps.util.ThemeUtils;
|
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
import app.organicmaps.util.ThemeUtils;
|
||||||
|
import app.organicmaps.widget.WheelProgressView;
|
||||||
|
import com.google.android.material.imageview.ShapeableImageView;
|
||||||
|
|
||||||
public class DownloaderStatusIcon
|
public class DownloaderStatusIcon
|
||||||
{
|
{
|
||||||
@@ -67,8 +64,10 @@ public class DownloaderStatusIcon
|
|||||||
|
|
||||||
protected void updateIcon(CountryItem country)
|
protected void updateIcon(CountryItem country)
|
||||||
{
|
{
|
||||||
@AttrRes int iconAttr = selectIcon(country);
|
@AttrRes
|
||||||
@DrawableRes int icon = resolveIcon(iconAttr);
|
int iconAttr = selectIcon(country);
|
||||||
|
@DrawableRes
|
||||||
|
int icon = resolveIcon(iconAttr);
|
||||||
|
|
||||||
mIcon.setImageResource(icon);
|
mIcon.setImageResource(icon);
|
||||||
}
|
}
|
||||||
@@ -76,8 +75,8 @@ public class DownloaderStatusIcon
|
|||||||
public void update(CountryItem country)
|
public void update(CountryItem country)
|
||||||
{
|
{
|
||||||
boolean pending = (country.status == CountryItem.STATUS_ENQUEUED);
|
boolean pending = (country.status == CountryItem.STATUS_ENQUEUED);
|
||||||
boolean inProgress = (country.status == CountryItem.STATUS_PROGRESS ||
|
boolean inProgress =
|
||||||
country.status == CountryItem.STATUS_APPLYING || pending);
|
(country.status == CountryItem.STATUS_PROGRESS || country.status == CountryItem.STATUS_APPLYING || pending);
|
||||||
|
|
||||||
UiUtils.showIf(inProgress, mProgress);
|
UiUtils.showIf(inProgress, mProgress);
|
||||||
UiUtils.showIf(!inProgress, mIcon);
|
UiUtils.showIf(!inProgress, mIcon);
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import android.app.Activity;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
import app.organicmaps.widget.SearchToolbarController;
|
|
||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
|
import app.organicmaps.widget.SearchToolbarController;
|
||||||
|
|
||||||
class DownloaderToolbarController extends SearchToolbarController
|
class DownloaderToolbarController extends SearchToolbarController
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,13 +4,8 @@ import android.location.Location;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
|
|
||||||
import com.google.android.material.button.MaterialButton;
|
|
||||||
import com.google.android.material.textview.MaterialTextView;
|
|
||||||
|
|
||||||
import app.organicmaps.MwmActivity;
|
import app.organicmaps.MwmActivity;
|
||||||
import app.organicmaps.MwmApplication;
|
import app.organicmaps.MwmApplication;
|
||||||
import app.organicmaps.R;
|
import app.organicmaps.R;
|
||||||
@@ -23,7 +18,8 @@ import app.organicmaps.sdk.util.StringUtils;
|
|||||||
import app.organicmaps.sdk.util.UiUtils;
|
import app.organicmaps.sdk.util.UiUtils;
|
||||||
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
||||||
import app.organicmaps.widget.WheelProgressView;
|
import app.organicmaps.widget.WheelProgressView;
|
||||||
|
import com.google.android.material.button.MaterialButton;
|
||||||
|
import com.google.android.material.textview.MaterialTextView;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
||||||
@@ -43,8 +39,7 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
@Nullable
|
@Nullable
|
||||||
private CountryItem mCurrentCountry;
|
private CountryItem mCurrentCountry;
|
||||||
|
|
||||||
private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback()
|
private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||||
{
|
{
|
||||||
@@ -80,15 +75,15 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final MapManager.CurrentCountryChangedListener mCountryChangedListener = new MapManager.CurrentCountryChangedListener()
|
private final MapManager.CurrentCountryChangedListener mCountryChangedListener =
|
||||||
{
|
new MapManager.CurrentCountryChangedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCurrentCountryChanged(String countryId)
|
public void onCurrentCountryChanged(String countryId)
|
||||||
{
|
{
|
||||||
mCurrentCountry = (TextUtils.isEmpty(countryId) ? null : CountryItem.fill(countryId));
|
mCurrentCountry = (TextUtils.isEmpty(countryId) ? null : CountryItem.fill(countryId));
|
||||||
updateState(true);
|
updateState(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void updateState(boolean shouldAutoDownload)
|
public void updateState(boolean shouldAutoDownload)
|
||||||
{
|
{
|
||||||
@@ -97,7 +92,8 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
|
|
||||||
private static boolean isMapDownloading(@Nullable CountryItem country)
|
private static boolean isMapDownloading(@Nullable CountryItem country)
|
||||||
{
|
{
|
||||||
if (country == null) return false;
|
if (country == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
boolean enqueued = country.status == CountryItem.STATUS_ENQUEUED;
|
boolean enqueued = country.status == CountryItem.STATUS_ENQUEUED;
|
||||||
boolean progress = country.status == CountryItem.STATUS_PROGRESS;
|
boolean progress = country.status == CountryItem.STATUS_PROGRESS;
|
||||||
@@ -112,18 +108,16 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
|
|
||||||
private void updateStateInternal(boolean shouldAutoDownload)
|
private void updateStateInternal(boolean shouldAutoDownload)
|
||||||
{
|
{
|
||||||
boolean showFrame = (mCurrentCountry != null &&
|
boolean showFrame =
|
||||||
!mCurrentCountry.present &&
|
(mCurrentCountry != null && !mCurrentCountry.present && !RoutingController.get().isNavigating());
|
||||||
!RoutingController.get().isNavigating());
|
|
||||||
if (showFrame)
|
if (showFrame)
|
||||||
{
|
{
|
||||||
boolean enqueued = (mCurrentCountry.status == CountryItem.STATUS_ENQUEUED);
|
boolean enqueued = (mCurrentCountry.status == CountryItem.STATUS_ENQUEUED);
|
||||||
boolean progress = (mCurrentCountry.status == CountryItem.STATUS_PROGRESS ||
|
boolean progress = (mCurrentCountry.status == CountryItem.STATUS_PROGRESS
|
||||||
mCurrentCountry.status == CountryItem.STATUS_APPLYING);
|
|| mCurrentCountry.status == CountryItem.STATUS_APPLYING);
|
||||||
boolean failed = (mCurrentCountry.status == CountryItem.STATUS_FAILED);
|
boolean failed = (mCurrentCountry.status == CountryItem.STATUS_FAILED);
|
||||||
|
|
||||||
showFrame = (enqueued || progress || failed ||
|
showFrame = (enqueued || progress || failed || mCurrentCountry.status == CountryItem.STATUS_DOWNLOADABLE);
|
||||||
mCurrentCountry.status == CountryItem.STATUS_DOWNLOADABLE);
|
|
||||||
|
|
||||||
if (showFrame)
|
if (showFrame)
|
||||||
{
|
{
|
||||||
@@ -145,7 +139,8 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
int roundedProgress = Math.round(mCurrentCountry.progress);
|
int roundedProgress = Math.round(mCurrentCountry.progress);
|
||||||
mProgress.setPending(false);
|
mProgress.setPending(false);
|
||||||
mProgress.setProgress(roundedProgress);
|
mProgress.setProgress(roundedProgress);
|
||||||
sizeText = mActivity.getString(R.string.downloader_downloading) + " " + StringUtils.formatPercent(roundedProgress / 100.0);
|
sizeText = mActivity.getString(R.string.downloader_downloading) + " "
|
||||||
|
+ StringUtils.formatPercent(roundedProgress / 100.0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -158,26 +153,22 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
{
|
{
|
||||||
sizeText = StringUtils.getFileSizeString(mActivity.getApplicationContext(), mCurrentCountry.totalSize);
|
sizeText = StringUtils.getFileSizeString(mActivity.getApplicationContext(), mCurrentCountry.totalSize);
|
||||||
|
|
||||||
if (shouldAutoDownload &&
|
if (shouldAutoDownload && Config.isAutodownloadEnabled() && !sAutodownloadLocked && !failed
|
||||||
Config.isAutodownloadEnabled() &&
|
&& ConnectionState.INSTANCE.isWifiConnected())
|
||||||
!sAutodownloadLocked &&
|
|
||||||
!failed &&
|
|
||||||
ConnectionState.INSTANCE.isWifiConnected())
|
|
||||||
{
|
{
|
||||||
Location loc = MwmApplication.from(mActivity).getLocationHelper().getSavedLocation();
|
Location loc = MwmApplication.from(mActivity).getLocationHelper().getSavedLocation();
|
||||||
if (loc != null)
|
if (loc != null)
|
||||||
{
|
{
|
||||||
String country = MapManager.nativeFindCountry(loc.getLatitude(), loc.getLongitude());
|
String country = MapManager.nativeFindCountry(loc.getLatitude(), loc.getLongitude());
|
||||||
if (TextUtils.equals(mCurrentCountry.id, country) &&
|
if (TextUtils.equals(mCurrentCountry.id, country)
|
||||||
MapManager.nativeHasSpaceToDownloadCountry(country))
|
&& MapManager.nativeHasSpaceToDownloadCountry(country))
|
||||||
{
|
{
|
||||||
MapManager.startDownload(mCurrentCountry.id);
|
MapManager.startDownload(mCurrentCountry.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mButton.setText(failed ? R.string.downloader_retry
|
mButton.setText(failed ? R.string.downloader_retry : R.string.download);
|
||||||
: R.string.download);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,37 +198,39 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
|
|||||||
MapManager.nativeCancel(mCurrentCountry.id);
|
MapManager.nativeCancel(mCurrentCountry.id);
|
||||||
setAutodownloadLocked(true);
|
setAutodownloadLocked(true);
|
||||||
});
|
});
|
||||||
mButton.setOnClickListener(v -> MapManager.warnOn3g(mActivity, mCurrentCountry == null ? null :
|
mButton.setOnClickListener(
|
||||||
mCurrentCountry.id, () -> {
|
v -> MapManager.warnOn3g(mActivity, mCurrentCountry == null ? null : mCurrentCountry.id, () -> {
|
||||||
if (mCurrentCountry == null)
|
if (mCurrentCountry == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boolean retry = (mCurrentCountry.status == CountryItem.STATUS_FAILED);
|
boolean retry = (mCurrentCountry.status == CountryItem.STATUS_FAILED);
|
||||||
if (retry)
|
if (retry)
|
||||||
{
|
{
|
||||||
MapManager.retryDownload(mCurrentCountry.id);
|
MapManager.retryDownload(mCurrentCountry.id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MapManager.startDownload(mCurrentCountry.id);
|
MapManager.startDownload(mCurrentCountry.id);
|
||||||
mActivity.requestPostNotificationsPermission();
|
mActivity.requestPostNotificationsPermission();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(mFrame, PaddingInsetsListener.allSides());
|
ViewCompat.setOnApplyWindowInsetsListener(mFrame, PaddingInsetsListener.allSides());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackStarted(boolean collapsed) {}
|
public void onTrackStarted(boolean collapsed)
|
||||||
|
{}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackFinished(boolean collapsed) {}
|
public void onTrackFinished(boolean collapsed)
|
||||||
|
{}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackLeftAnimation(float offset)
|
public void onTrackLeftAnimation(float offset)
|
||||||
{
|
{
|
||||||
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)mFrame.getLayoutParams();
|
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mFrame.getLayoutParams();
|
||||||
lp.leftMargin = (int)offset;
|
lp.leftMargin = (int) offset;
|
||||||
mFrame.setLayoutParams(lp);
|
mFrame.setLayoutParams(lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user