diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index d18ded385a..64624045aa 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -624,8 +624,7 @@
+ android:configChanges="screenLayout|screenSize"/>
+
diff --git a/android/src/app/organicmaps/ChartController.java b/android/src/app/organicmaps/ChartController.java
index e16ad9c42c..7f8a9e35d7 100644
--- a/android/src/app/organicmaps/ChartController.java
+++ b/android/src/app/organicmaps/ChartController.java
@@ -8,6 +8,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
@@ -140,7 +141,7 @@ public class ChartController implements OnChartValueSelectedListener, Initializa
y.setLabelCount(CHART_Y_LABEL_COUNT, false);
y.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
y.setDrawGridLines(true);
- y.setGridColor(mContext.getResources().getColor(R.color.black_12));
+ y.setGridColor(ContextCompat.getColor(mContext, R.color.black_12));
y.setEnabled(true);
y.setTextColor(Color.TRANSPARENT);
y.setAxisLineColor(Color.TRANSPARENT);
@@ -172,7 +173,7 @@ public class ChartController implements OnChartValueSelectedListener, Initializa
set.setFillColor(color);
set.setDrawHorizontalHighlightIndicator(false);
set.setHighlightLineWidth(lineThickness);
- set.setHighLightColor(mContext.getResources().getColor(R.color.base_accent_transparent));
+ set.setHighLightColor(ContextCompat.getColor(mContext, R.color.base_accent_transparent));
LineData data = new LineData(set);
data.setValueTextSize(mContext.getResources().getDimensionPixelSize(R.dimen.text_size_icon_title));
diff --git a/android/src/app/organicmaps/DownloadResourcesLegacyActivity.java b/android/src/app/organicmaps/DownloadResourcesLegacyActivity.java
index e42fd4300c..a179309861 100644
--- a/android/src/app/organicmaps/DownloadResourcesLegacyActivity.java
+++ b/android/src/app/organicmaps/DownloadResourcesLegacyActivity.java
@@ -359,7 +359,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
if (ParsedMwmRequest.getCurrentRequest() != null)
{
// Wait for the result from MwmActivity for API callers.
- startActivityForResult(intent, REQ_CODE_API_RESULT);
+ UiUtils.startActivityForResult(this, intent, REQ_CODE_API_RESULT);
return;
}
}
diff --git a/android/src/app/organicmaps/MwmActivity.java b/android/src/app/organicmaps/MwmActivity.java
index 0dfed4c191..a2d6e41b40 100644
--- a/android/src/app/organicmaps/MwmActivity.java
+++ b/android/src/app/organicmaps/MwmActivity.java
@@ -416,6 +416,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
));
}
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
private void updateViewsInsets()
{
mPointChooser.setOnApplyWindowInsetsListener((view, windowInsets) -> {
@@ -957,7 +958,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
intent.hasExtra(EXTRA_TASK) &&
((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0))
{
- final MapTask mapTask = (MapTask) intent.getSerializableExtra(EXTRA_TASK);
+ final MapTask mapTask = Utils.getSerializable(intent, EXTRA_TASK, MapTask.class);
mTasks.add(mapTask);
intent.removeExtra(EXTRA_TASK);
@@ -1388,6 +1389,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
@Override
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
public void onRoutingPlanStartAnimate(boolean show)
{
int offset = mCurrentWindowInsets.getSystemWindowInsetTop();
diff --git a/android/src/app/organicmaps/MwmJobIntentService.java b/android/src/app/organicmaps/MwmJobIntentService.java
index 8be35db3a8..a53aed33fc 100644
--- a/android/src/app/organicmaps/MwmJobIntentService.java
+++ b/android/src/app/organicmaps/MwmJobIntentService.java
@@ -8,6 +8,7 @@ import androidx.core.app.JobIntentService;
import app.organicmaps.util.CrashlyticsUtils;
import app.organicmaps.util.log.Logger;
+@SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/4531
public abstract class MwmJobIntentService extends JobIntentService
{
private static final String TAG = MwmJobIntentService.class.getSimpleName();
diff --git a/android/src/app/organicmaps/background/Notifier.java b/android/src/app/organicmaps/background/Notifier.java
index a49808bd05..a1f388bb1b 100644
--- a/android/src/app/organicmaps/background/Notifier.java
+++ b/android/src/app/organicmaps/background/Notifier.java
@@ -12,6 +12,7 @@ import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
+import androidx.core.content.ContextCompat;
import app.organicmaps.MwmActivity;
import app.organicmaps.R;
@@ -96,7 +97,7 @@ public final class Notifier
return new NotificationCompat.Builder(mContext, channel)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_notification)
- .setColor(UiUtils.getNotificationColor(mContext))
+ .setColor(ContextCompat.getColor(mContext, R.color.notification))
.setContentTitle(title)
.setContentText(content)
.setTicker(getTicker(title, content))
diff --git a/android/src/app/organicmaps/background/OsmUploadService.java b/android/src/app/organicmaps/background/OsmUploadService.java
index a6fef8be03..ab3f2e5253 100644
--- a/android/src/app/organicmaps/background/OsmUploadService.java
+++ b/android/src/app/organicmaps/background/OsmUploadService.java
@@ -15,6 +15,7 @@ public class OsmUploadService extends MwmJobIntentService
/**
* Starts this service to upload map edits to osm servers.
*/
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/4531
public static void startActionUploadOsmChanges(@NonNull Context context)
{
final Intent intent = new Intent(context, OsmUploadService.class);
diff --git a/android/src/app/organicmaps/base/BaseMwmFragment.java b/android/src/app/organicmaps/base/BaseMwmFragment.java
index 953f0ecfdf..9f6efcbcd6 100644
--- a/android/src/app/organicmaps/base/BaseMwmFragment.java
+++ b/android/src/app/organicmaps/base/BaseMwmFragment.java
@@ -5,6 +5,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
import app.organicmaps.util.Utils;
diff --git a/android/src/app/organicmaps/base/BaseMwmFragmentActivity.java b/android/src/app/organicmaps/base/BaseMwmFragmentActivity.java
index ed9e9f8102..1e535d2fab 100644
--- a/android/src/app/organicmaps/base/BaseMwmFragmentActivity.java
+++ b/android/src/app/organicmaps/base/BaseMwmFragmentActivity.java
@@ -14,6 +14,8 @@ import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.ContextCompat;
+import androidx.core.content.IntentCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentFactory;
import androidx.fragment.app.FragmentManager;
@@ -72,7 +74,7 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
// An intent that was skipped due to core wasn't initialized has to be used
// as a target intent for this activity, otherwise all input extras will be lost
// in a splash activity loop.
- Intent initialIntent = getIntent().getParcelableExtra(SplashActivity.EXTRA_INITIAL_INTENT);
+ Intent initialIntent = Utils.getParcelable(getIntent(), SplashActivity.EXTRA_INITIAL_INTENT, Intent.class);
if (initialIntent != null)
setIntent(initialIntent);
@@ -100,13 +102,6 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
if (layoutId != 0)
setContentView(layoutId);
- // Use full-screen on Kindle Fire only
- if (Utils.isAmazonDevice())
- {
- getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);
- getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
- }
-
attachDefaultFragment();
mBaseDelegate.onSafeCreate();
mSafeCreated = true;
diff --git a/android/src/app/organicmaps/base/MediaPlayerWrapper.java b/android/src/app/organicmaps/base/MediaPlayerWrapper.java
index 7cf7e13d26..ed4c7bb37e 100644
--- a/android/src/app/organicmaps/base/MediaPlayerWrapper.java
+++ b/android/src/app/organicmaps/base/MediaPlayerWrapper.java
@@ -112,6 +112,7 @@ public class MediaPlayerWrapper
return app.getMediaPlayer();
}
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3632
private static class InitPlayerTask extends AsyncTask
{
@NonNull
diff --git a/android/src/app/organicmaps/bookmarks/BookmarksListFragment.java b/android/src/app/organicmaps/bookmarks/BookmarksListFragment.java
index ab8bc3a7f7..8705861cc6 100644
--- a/android/src/app/organicmaps/bookmarks/BookmarksListFragment.java
+++ b/android/src/app/organicmaps/bookmarks/BookmarksListFragment.java
@@ -777,6 +777,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment
{
private static final String TAG = ChunkTask.class.getSimpleName();
diff --git a/android/src/app/organicmaps/downloader/CountrySuggestFragment.java b/android/src/app/organicmaps/downloader/CountrySuggestFragment.java
index 763cf30541..af9631a728 100644
--- a/android/src/app/organicmaps/downloader/CountrySuggestFragment.java
+++ b/android/src/app/organicmaps/downloader/CountrySuggestFragment.java
@@ -11,6 +11,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmFragment;
@@ -208,8 +209,10 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl
}
else if (id == R.id.btn__select_map)
{
- BaseMwmFragmentActivity activity = Utils.castTo(requireActivity());
- activity.replaceFragment(DownloaderFragment.class, null, null);
+ final FragmentActivity fragmentActivity = requireActivity();
+ if (!(fragmentActivity instanceof BaseMwmFragmentActivity))
+ throw new IllegalStateException("Activity is not instance of BaseMwmFragmentActivity");
+ ((BaseMwmFragmentActivity) fragmentActivity).replaceFragment(DownloaderFragment.class, null, null);
}
else if (id == R.id.wpv__download_progress)
MapManager.nativeCancel(mDownloadingCountry.id);
diff --git a/android/src/app/organicmaps/downloader/DownloaderFragment.java b/android/src/app/organicmaps/downloader/DownloaderFragment.java
index 5d0e0a3a29..e8020b8862 100644
--- a/android/src/app/organicmaps/downloader/DownloaderFragment.java
+++ b/android/src/app/organicmaps/downloader/DownloaderFragment.java
@@ -203,6 +203,7 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment {
+ view.setPadding(windowInsets.getSystemWindowInsetLeft(), view.getPaddingTop(),
+ view.getPaddingRight(), view.getPaddingBottom());
+ return windowInsets;
+ });
+ }
+
public NavigationController(AppCompatActivity activity, @NonNull MapButtonsController mapButtonsController, View.OnClickListener onSettingsClickListener)
{
mFrame = activity.findViewById(R.id.navigation_frame);
@@ -93,11 +103,7 @@ public class NavigationController implements Application.ActivityLifecycleCallba
mNextTurnDistance = turnFrame.findViewById(R.id.distance);
mCircleExit = turnFrame.findViewById(R.id.circle_exit);
- topFrame.findViewById(R.id.nav_next_turn_container).setOnApplyWindowInsetsListener((view, windowInsets) -> {
- view.setPadding(windowInsets.getSystemWindowInsetLeft(), view.getPaddingTop(),
- view.getPaddingRight(), view.getPaddingBottom());
- return windowInsets;
- });
+ addWindowsInsets(topFrame);
mNextNextTurnFrame = topFrame.findViewById(R.id.nav_next_next_turn_frame);
mNextNextTurnImage = mNextNextTurnFrame.findViewById(R.id.turn);
diff --git a/android/src/app/organicmaps/routing/NavigationService.java b/android/src/app/organicmaps/routing/NavigationService.java
index 6e45a4da72..0ba7c11114 100644
--- a/android/src/app/organicmaps/routing/NavigationService.java
+++ b/android/src/app/organicmaps/routing/NavigationService.java
@@ -13,6 +13,7 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.location.Location;
import android.os.Binder;
+import android.os.Build;
import android.os.IBinder;
import android.widget.RemoteViews;
@@ -185,13 +186,14 @@ public class NavigationService extends Service
{
Intent stopSelf = new Intent(this, NavigationService.class);
stopSelf.putExtra(EXTRA_STOP_SERVICE, true);
- PendingIntent pStopSelf = PendingIntent.getService(this, 0,
- stopSelf, PendingIntent.FLAG_CANCEL_CURRENT);
+ final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE;
+ PendingIntent pStopSelf = PendingIntent.getService(this, 0, stopSelf,
+ PendingIntent.FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE);
// TODO (@velichkomarija): restore navigation from notification.
PendingIntent activityPendingIntent = PendingIntent
.getActivity(this, 0,
- new Intent(this, MwmActivity.class), 0);
+ new Intent(this, MwmActivity.class), FLAG_IMMUTABLE);
Builder builder = new Builder(this, CHANNEL_ID)
.addAction(R.drawable.ic_cancel, getString(R.string.button_exit),
diff --git a/android/src/app/organicmaps/search/SearchAdapter.java b/android/src/app/organicmaps/search/SearchAdapter.java
index bb5630fe2a..36497b536f 100644
--- a/android/src/app/organicmaps/search/SearchAdapter.java
+++ b/android/src/app/organicmaps/search/SearchAdapter.java
@@ -16,6 +16,7 @@ import androidx.annotation.AttrRes;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.R;
@@ -234,12 +235,12 @@ class SearchAdapter extends RecyclerView.Adapter {
final boolean result = StoragePathManager.moveStorage(newPath, oldPath);
diff --git a/android/src/app/organicmaps/util/StorageUtils.java b/android/src/app/organicmaps/util/StorageUtils.java
index 7492bf052f..a3693b557d 100644
--- a/android/src/app/organicmaps/util/StorageUtils.java
+++ b/android/src/app/organicmaps/util/StorageUtils.java
@@ -97,8 +97,7 @@ public class StorageUtils
{
try
{
- return application.getPackageManager()
- .getApplicationInfo(BuildConfig.APPLICATION_ID, 0).sourceDir;
+ return Utils.getApplicationInfo(application.getPackageManager(), BuildConfig.APPLICATION_ID, 0).sourceDir;
}
catch (final PackageManager.NameNotFoundException e)
{
diff --git a/android/src/app/organicmaps/util/UiUtils.java b/android/src/app/organicmaps/util/UiUtils.java
index f3a923e8a5..fb612d6b80 100644
--- a/android/src/app/organicmaps/util/UiUtils.java
+++ b/android/src/app/organicmaps/util/UiUtils.java
@@ -4,6 +4,7 @@ import android.animation.Animator;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -11,10 +12,8 @@ import android.graphics.Color;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
-import android.text.Html;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
-import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TouchDelegate;
@@ -25,7 +24,6 @@ import android.view.Window;
import android.view.WindowInsets;
import android.widget.Button;
import android.widget.TextView;
-import android.widget.Toast;
import androidx.annotation.AnyRes;
import androidx.annotation.AttrRes;
@@ -34,13 +32,18 @@ import androidx.annotation.DimenRes;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
+import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.WindowInsetsControllerCompat;
+import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
+
import com.google.android.material.textfield.TextInputLayout;
+
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
@@ -65,7 +68,7 @@ public final class UiUtils
{
TextView policyView = view.findViewById(id);
Resources rs = policyView.getResources();
- policyView.setText(Html.fromHtml(rs.getString(stringId, link)));
+ policyView.setText(Utils.fromHtml(rs.getString(stringId, link)));
policyView.setMovementMethod(LinkMovementMethod.getInstance());
}
@@ -91,7 +94,7 @@ public final class UiUtils
public static void waitLayout(final View view, @NonNull final ViewTreeObserver.OnGlobalLayoutListener callback) {
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @SuppressWarnings("deprecation")
+
@Override
public void onGlobalLayout() {
// viewTreeObserver can be dead(isAlive() == false), we should get a new one here.
@@ -335,7 +338,7 @@ public final class UiUtils
layout.getEditText().setError(error == 0 ? null : layout.getContext().getString(error));
layout.getEditText().setTextColor(error == 0 ? ThemeUtils.getColor(layout.getContext(), android.R.attr.textColorPrimary)
- : layout.getContext().getResources().getColor(R.color.base_red));
+ : ContextCompat.getColor(layout.getContext(), R.color.base_red));
}
public static boolean isLandscape(@NonNull Context context)
@@ -415,30 +418,35 @@ public final class UiUtils
setViewInsetsPaddingNoBottom(view, windowInsets);
}
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
public static void setViewInsetsPadding(View view, WindowInsets windowInsets)
{
view.setPadding(windowInsets.getSystemWindowInsetLeft(), windowInsets.getSystemWindowInsetTop(),
windowInsets.getSystemWindowInsetRight(), windowInsets.getSystemWindowInsetBottom());
}
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
public static void setViewInsetsPaddingNoTop(View view, WindowInsets windowInsets)
{
view.setPadding(windowInsets.getSystemWindowInsetLeft(), view.getPaddingTop(),
windowInsets.getSystemWindowInsetRight(), windowInsets.getSystemWindowInsetBottom());
}
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
public static void setViewInsetsPaddingSides(View view, WindowInsets windowInsets)
{
view.setPadding(windowInsets.getSystemWindowInsetLeft(), view.getPaddingTop(),
windowInsets.getSystemWindowInsetRight(), view.getPaddingBottom());
}
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
public static void setViewInsetsPaddingBottom(View view, WindowInsets windowInsets)
{
view.setPadding(view.getPaddingLeft(), view.getPaddingTop(),
view.getPaddingRight(), windowInsets.getSystemWindowInsetBottom());
}
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
public static void setViewInsetsPaddingNoBottom(View view, WindowInsets windowInsets)
{
view.setPadding(windowInsets.getSystemWindowInsetLeft(), windowInsets.getSystemWindowInsetTop(),
@@ -530,19 +538,6 @@ public final class UiUtils
});
}
- @ColorInt
- public static int getNotificationColor(@NonNull Context context)
- {
- return context.getResources().getColor(R.color.notification);
- }
-
- public static void showToastAtTop(@NonNull Context context, @StringRes int stringId)
- {
- Toast toast = Toast.makeText(context, stringId, Toast.LENGTH_LONG);
- toast.setGravity(Gravity.TOP, 0, 0);
- toast.show();
- }
-
public static void showRecyclerItemView(boolean show, @NonNull View view)
{
if (show)
@@ -559,6 +554,18 @@ public final class UiUtils
}
}
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3630
+ public static void startActivityForResult(@NonNull AppCompatActivity activity, @NonNull Intent intent, int requestCode)
+ {
+ activity.startActivityForResult(intent, requestCode);
+ }
+
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3630
+ public static void startActivityForResult(@NonNull Fragment fragment, @NonNull Intent intent, int requestCode)
+ {
+ fragment.startActivityForResult(intent, requestCode);
+ }
+
// utility class
private UiUtils() {}
}
diff --git a/android/src/app/organicmaps/util/Utils.java b/android/src/app/organicmaps/util/Utils.java
index 7338927e82..a599a68d60 100644
--- a/android/src/app/organicmaps/util/Utils.java
+++ b/android/src/app/organicmaps/util/Utils.java
@@ -6,12 +6,16 @@ import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
+import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
@@ -34,6 +38,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.snackbar.Snackbar;
+
import app.organicmaps.BuildConfig;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
@@ -44,6 +49,7 @@ import app.organicmaps.util.log.LogsManager;
import java.io.Closeable;
import java.io.IOException;
+import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.text.DateFormat;
import java.text.NumberFormat;
@@ -88,11 +94,6 @@ public class Utils
return Build.VERSION.SDK_INT >= target;
}
- public static boolean isAmazonDevice()
- {
- return "Amazon".equalsIgnoreCase(Build.MANUFACTURER);
- }
-
/**
* Enable to keep screen on.
* Disable to let system turn it off automatically.
@@ -105,16 +106,23 @@ public class Utils
w.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
- public static void showOnLockScreen(boolean enable, Activity activity)
+ @SuppressWarnings("deprecation")
+ private static void showOnLockScreenOld(boolean enable, Activity activity)
{
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
- activity.setShowWhenLocked(enable);
- else if (enable)
+ if (enable)
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
else
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
+ public static void showOnLockScreen(boolean enable, Activity activity)
+ {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1)
+ showOnLockScreenOld(enable, activity);
+ else
+ activity.setShowWhenLocked(enable);
+ }
+
public static void showSnackbar(@NonNull View view, @NonNull String message)
{
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
@@ -151,9 +159,18 @@ public class Utils
showSnackbarAbove(view, viewAbove, message);
}
+ @SuppressWarnings("deprecated")
+ private static @Nullable ResolveInfo resolveActivity(@NonNull PackageManager pm, @NonNull Intent intent, int flags)
+ {
+ return pm.resolveActivity(intent, flags);
+ }
+
public static boolean isIntentSupported(@NonNull Context context, @NonNull Intent intent)
{
- return context.getPackageManager().resolveActivity(intent, 0) != null;
+ final PackageManager pm = context.getPackageManager();
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
+ return resolveActivity(pm, intent, 0) != null;
+ return pm.resolveActivity(intent, PackageManager.ResolveInfoFlags.of(0)) != null;
}
public static @Nullable Intent makeSystemLocationSettingIntent(@NonNull Context context)
@@ -206,21 +223,6 @@ public class Utils
return "[" + joined + "]";
}
- public static boolean isPackageInstalled(@NonNull Context context, String packageUri)
- {
- PackageManager pm = context.getPackageManager();
- boolean installed;
- try
- {
- pm.getPackageInfo(packageUri, PackageManager.GET_ACTIVITIES);
- installed = true;
- } catch (PackageManager.NameNotFoundException e)
- {
- installed = false;
- }
- return installed;
- }
-
public static Uri buildMailUri(String to, String subject, String body)
{
String uriString = Constants.Url.MAILTO_SCHEME + Uri.encode(to) +
@@ -250,7 +252,7 @@ public class Utils
try
{
// Exception is thrown if we don't have installed Facebook application.
- activity.getPackageManager().getPackageInfo(Constants.Package.FB_PACKAGE, 0);
+ getPackageInfo(activity.getPackageManager(), Constants.Package.FB_PACKAGE, 0);
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Constants.Url.FB_OM_COMMUNITY_NATIVE)));
} catch (final Exception e)
{
@@ -312,13 +314,6 @@ public class Utils
return url.startsWith("http://") || url.startsWith("https://");
}
- @NonNull
- public static T castTo(@NonNull Object instance)
- {
- // Noinspection unchecked
- return (T) instance;
- }
-
public static void closeSafely(@NonNull Closeable... closeable)
{
for (Closeable each : closeable)
@@ -408,7 +403,7 @@ public class Utils
try
{
PackageManager pm = context.getPackageManager();
- pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
+ getPackageInfo(pm, packageName, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e)
{
@@ -812,19 +807,93 @@ public class Utils
}
}
- @Nullable
- public static T getParcelable(Bundle args, String key, Class clazz)
- {
- args.setClassLoader(clazz.getClassLoader());
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
- return args.getParcelable(key, clazz);
- return getParcelableOld(args, key);
- }
-
@SuppressWarnings({"deprecation", "unchecked"})
@Nullable
private static T getParcelableOld(Bundle args, String key)
{
return (T) args.getParcelable(key);
}
+
+ @Nullable
+ public static T getParcelable(@NonNull Intent intent, String key, Class clazz)
+ {
+ final Bundle args = intent.getExtras();
+ return (args == null) ? null : getParcelable(args, key, clazz);
+ }
+
+ @Nullable
+ public static T getParcelable(@NonNull Bundle args, String key, Class clazz)
+ {
+ args.setClassLoader(clazz.getClassLoader());
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
+ return getParcelableOld(args, key);
+ return args.getParcelable(key, clazz);
+ }
+
+ @SuppressWarnings({"deprecation", "unchecked"})
+ @Nullable
+ private static T getSerializableOld(Bundle args, String key)
+ {
+ return (T) args.getSerializable(key);
+ }
+
+ @Nullable
+ public static T getSerializable(@NonNull Bundle args, String key, Class clazz)
+ {
+ args.setClassLoader(clazz.getClassLoader());
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
+ return getSerializableOld(args, key);
+ return args.getSerializable(key, clazz);
+ }
+
+ @Nullable
+ public static T getSerializable(@NonNull Intent intent, String key, Class clazz)
+ {
+ final Bundle args = intent.getExtras();
+ return (args == null) ? null : getSerializable(args, key, clazz);
+ }
+
+ @SuppressWarnings("deprecation")
+ private static Spanned fromHtmlOld(@NonNull String htmlDescription)
+ {
+ return Html.fromHtml(htmlDescription);
+ }
+
+ public static Spanned fromHtml(@NonNull String htmlDescription)
+ {
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N)
+ return fromHtmlOld(htmlDescription);
+ return Html.fromHtml(htmlDescription, Html.FROM_HTML_MODE_LEGACY);
+ }
+
+ @SuppressWarnings("deprecation")
+ private static ApplicationInfo getApplicationInfoOld(@NonNull PackageManager manager, @NonNull String packageName, int flags)
+ throws PackageManager.NameNotFoundException
+ {
+ return manager.getApplicationInfo(packageName, flags);
+ }
+
+ public static ApplicationInfo getApplicationInfo(@NonNull PackageManager manager, @NonNull String packageName,
+ int flags)
+ throws PackageManager.NameNotFoundException
+ {
+ if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
+ return getApplicationInfoOld(manager, packageName, flags);
+ return manager.getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags));
+ }
+
+ @SuppressWarnings("deprecation")
+ private static PackageInfo getPackageInfoOld(@NonNull PackageManager manager, @NonNull String packageName, int flags)
+ throws PackageManager.NameNotFoundException
+ {
+ return manager.getPackageInfo(packageName, flags);
+ }
+
+ public static PackageInfo getPackageInfo(@NonNull PackageManager manager, @NonNull String packageName, int flags)
+ throws PackageManager.NameNotFoundException
+ {
+ if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
+ return getPackageInfoOld(manager, packageName, flags);
+ return manager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(flags));
+ }
}
diff --git a/android/src/app/organicmaps/widget/StackedButtonsDialog.java b/android/src/app/organicmaps/widget/StackedButtonsDialog.java
index 195bfa425d..12a2a23cac 100644
--- a/android/src/app/organicmaps/widget/StackedButtonsDialog.java
+++ b/android/src/app/organicmaps/widget/StackedButtonsDialog.java
@@ -132,8 +132,8 @@ public class StackedButtonsDialog extends AppCompatDialog implements View.OnClic
{
mContext = context;
mTitle = mContext.getString(android.R.string.dialog_alert_title);
- mPositive = mContext.getString(android.R.string.ok);
- mNegative = mContext.getString(android.R.string.no);
+ mPositive = mContext.getString(R.string.ok);
+ mNegative = mContext.getString(R.string.cancel);
}
@NonNull
diff --git a/android/src/app/organicmaps/widget/placepage/BookmarkColorDialogFragment.java b/android/src/app/organicmaps/widget/placepage/BookmarkColorDialogFragment.java
index 82ff6299a3..925fed672d 100644
--- a/android/src/app/organicmaps/widget/placepage/BookmarkColorDialogFragment.java
+++ b/android/src/app/organicmaps/widget/placepage/BookmarkColorDialogFragment.java
@@ -1,5 +1,6 @@
package app.organicmaps.widget.placepage;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -58,6 +59,7 @@ public class BookmarkColorDialogFragment extends BaseMwmDialogFragment
final IconsAdapter adapter = new IconsAdapter(requireActivity(), icons);
adapter.chooseItem(mIconColor);
+ @SuppressLint("InflateParams")
final GridView gView = (GridView) LayoutInflater.from(requireActivity()).inflate(R.layout.fragment_color_grid, null);
gView.setAdapter(adapter);
gView.setOnItemClickListener(new AdapterView.OnItemClickListener()
diff --git a/android/src/app/organicmaps/widget/placepage/EditBookmarkFragment.java b/android/src/app/organicmaps/widget/placepage/EditBookmarkFragment.java
index 869831d30d..a5229925bc 100644
--- a/android/src/app/organicmaps/widget/placepage/EditBookmarkFragment.java
+++ b/android/src/app/organicmaps/widget/placepage/EditBookmarkFragment.java
@@ -15,6 +15,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentFactory;
import androidx.fragment.app.FragmentManager;
import app.organicmaps.R;
@@ -60,7 +61,8 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
args.putLong(EXTRA_CATEGORY_ID, categoryId);
args.putLong(EXTRA_BOOKMARK_ID, bookmarkId);
String name = EditBookmarkFragment.class.getName();
- final EditBookmarkFragment fragment = (EditBookmarkFragment) Fragment.instantiate(context, name, args);
+ final FragmentFactory factory = manager.getFragmentFactory();
+ final EditBookmarkFragment fragment = (EditBookmarkFragment) factory.instantiate(context.getClassLoader(), name);
fragment.setArguments(args);
fragment.setEditBookmarkListener(listener);
fragment.show(manager, name);
@@ -165,12 +167,15 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
final Bundle args = new Bundle();
final List categories = BookmarkManager.INSTANCE.getCategories();
final int index = categories.indexOf(mBookmarkCategory);
-
args.putInt(ChooseBookmarkCategoryFragment.CATEGORY_POSITION, index);
+
+ final FragmentManager manager = getChildFragmentManager();
String className = ChooseBookmarkCategoryFragment.class.getName();
- ChooseBookmarkCategoryFragment frag =
- (ChooseBookmarkCategoryFragment) Fragment.instantiate(requireActivity(), className, args);
- frag.show(getChildFragmentManager(), null);
+ final FragmentFactory factory = manager.getFragmentFactory();
+ final ChooseBookmarkCategoryFragment frag =
+ (ChooseBookmarkCategoryFragment) factory.instantiate(getContext().getClassLoader(), className);
+ frag.setArguments(args);
+ frag.show(manager, null);
}
private void selectBookmarkColor()
@@ -180,23 +185,22 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
final Bundle args = new Bundle();
args.putInt(BookmarkColorDialogFragment.ICON_TYPE, mIcon.getColor());
- final BookmarkColorDialogFragment dialogFragment = (BookmarkColorDialogFragment) BookmarkColorDialogFragment.
- instantiate(requireActivity(), BookmarkColorDialogFragment.class.getName(), args);
- dialogFragment.setOnColorSetListener(new BookmarkColorDialogFragment.OnBookmarkColorChangeListener()
- {
- @Override
- public void onBookmarkColorSet(int colorPos)
- {
- final Icon newIcon = BookmarkManager.ICONS.get(colorPos);
- final String from = mIcon.getName();
- final String to = newIcon.getName();
- if (TextUtils.equals(from, to))
- return;
+ final FragmentManager manager = getChildFragmentManager();
+ String className = BookmarkColorDialogFragment.class.getName();
+ final FragmentFactory factory = manager.getFragmentFactory();
+ final BookmarkColorDialogFragment dialogFragment =
+ (BookmarkColorDialogFragment) factory.instantiate(getContext().getClassLoader(), className);
+ dialogFragment.setArguments(args);
+ dialogFragment.setOnColorSetListener(colorPos -> {
+ final Icon newIcon = BookmarkManager.ICONS.get(colorPos);
+ final String from = mIcon.getName();
+ final String to = newIcon.getName();
+ if (TextUtils.equals(from, to))
+ return;
- mIcon = newIcon;
- refreshColorMarker();
- }
+ mIcon = newIcon;
+ refreshColorMarker();
});
dialogFragment.show(requireActivity().getSupportFragmentManager(), null);
diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageBookmarkFragment.java b/android/src/app/organicmaps/widget/placepage/PlacePageBookmarkFragment.java
index d5b9dede75..664839dacf 100644
--- a/android/src/app/organicmaps/widget/placepage/PlacePageBookmarkFragment.java
+++ b/android/src/app/organicmaps/widget/placepage/PlacePageBookmarkFragment.java
@@ -104,7 +104,7 @@ public class PlacePageBookmarkFragment extends Fragment implements View.OnClickL
else
{
mTvBookmarkNote.setText(notes);
- Linkify.addLinks(mTvBookmarkNote, Linkify.ALL);
+ Linkify.addLinks(mTvBookmarkNote, Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS);
UiUtils.show(mTvBookmarkNote);
if (mWvBookmarkNote != null)
UiUtils.hide(mWvBookmarkNote);
diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageController.java b/android/src/app/organicmaps/widget/placepage/PlacePageController.java
index 95afb4a0e8..9899ce23d9 100644
--- a/android/src/app/organicmaps/widget/placepage/PlacePageController.java
+++ b/android/src/app/organicmaps/widget/placepage/PlacePageController.java
@@ -229,6 +229,7 @@ public class PlacePageController implements Initializable,
* Set the min and max height of the place page to prevent jumps when switching from one map object
* to the other.
*/
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
private void setPlacePageHeightBounds()
{
final int peekHeight = calculatePeekHeight();
@@ -273,6 +274,7 @@ public class PlacePageController implements Initializable,
* Using the animate param in setPeekHeight does not work when adding removing fragments
* from inside the place page so we manually animate the peek height with ValueAnimator
*/
+ @SuppressWarnings("deprecation") // https://github.com/organicmaps/organicmaps/issues/3631
private void animatePeekHeight(int peekHeight)
{
// Make sure to start from the current height of the place page
diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageOpeningHoursFragment.java b/android/src/app/organicmaps/widget/placepage/PlacePageOpeningHoursFragment.java
index dfd0891b38..d02840b440 100644
--- a/android/src/app/organicmaps/widget/placepage/PlacePageOpeningHoursFragment.java
+++ b/android/src/app/organicmaps/widget/placepage/PlacePageOpeningHoursFragment.java
@@ -10,6 +10,7 @@ import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
@@ -171,7 +172,7 @@ public class PlacePageOpeningHoursFragment extends Fragment implements Observer<
// Show that place is closed today.
if (!containsCurrentWeekday)
{
- refreshTodayOpeningHours(resources.getString(R.string.day_off_today), resources.getColor(R.color.base_red));
+ refreshTodayOpeningHours(resources.getString(R.string.day_off_today), ContextCompat.getColor(getContext(), R.color.base_red));
UiUtils.hide(mTodayNonBusinessTime);
}
}
diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageView.java b/android/src/app/organicmaps/widget/placepage/PlacePageView.java
index 7a84d7ccad..4a10fc2de2 100644
--- a/android/src/app/organicmaps/widget/placepage/PlacePageView.java
+++ b/android/src/app/organicmaps/widget/placepage/PlacePageView.java
@@ -20,6 +20,7 @@ import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Observer;
@@ -46,6 +47,7 @@ import app.organicmaps.routing.RoutingController;
import app.organicmaps.settings.RoadType;
import app.organicmaps.util.SharingUtils;
import app.organicmaps.util.StringUtils;
+import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.concurrency.UiThread;
import app.organicmaps.widget.ArrowView;
@@ -421,7 +423,7 @@ public class PlacePageView extends Fragment implements View.OnClickListener,
private void updateViewFragment(Class controllerClass, String fragmentTag, @IdRes int containerId, boolean enabled)
{
final FragmentManager fm = getChildFragmentManager();
- final T fragment = (T) fm.findFragmentByTag(fragmentTag);
+ final Fragment fragment = fm.findFragmentByTag(fragmentTag);
if (enabled && fragment == null)
{
fm.beginTransaction()
@@ -476,7 +478,7 @@ public class PlacePageView extends Fragment implements View.OnClickListener,
int end = text.lastIndexOf("★") + 1;
if (start > -1)
{
- sb.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.base_yellow)),
+ sb.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.base_yellow)),
start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
mTvSubtitle.setText(sb);
diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageWikipediaFragment.java b/android/src/app/organicmaps/widget/placepage/PlacePageWikipediaFragment.java
index 7a0007eb0f..19988c433a 100644
--- a/android/src/app/organicmaps/widget/placepage/PlacePageWikipediaFragment.java
+++ b/android/src/app/organicmaps/widget/placepage/PlacePageWikipediaFragment.java
@@ -1,7 +1,6 @@
package app.organicmaps.widget.placepage;
import android.os.Bundle;
-import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.view.LayoutInflater;
@@ -69,7 +68,7 @@ public class PlacePageWikipediaFragment extends Fragment implements Observer