From b2da0b5e25d75b444267adc350a5dd7463d71a73 Mon Sep 17 00:00:00 2001 From: Roman Tsisyk Date: Mon, 20 Feb 2023 08:37:36 +0200 Subject: [PATCH] [android] Fix or suppress warnings 100+ warnings left.. Signed-off-by: Roman Tsisyk --- android/AndroidManifest.xml | 3 +- android/res/xml/locales_config.xml | 1 + .../src/app/organicmaps/ChartController.java | 5 +- .../DownloadResourcesLegacyActivity.java | 2 +- android/src/app/organicmaps/MwmActivity.java | 4 +- .../app/organicmaps/MwmJobIntentService.java | 1 + .../app/organicmaps/background/Notifier.java | 3 +- .../background/OsmUploadService.java | 1 + .../app/organicmaps/base/BaseMwmFragment.java | 1 + .../base/BaseMwmFragmentActivity.java | 11 +- .../organicmaps/base/MediaPlayerWrapper.java | 1 + .../bookmarks/BookmarksListFragment.java | 1 + .../app/organicmaps/bookmarks/Holders.java | 3 +- .../app/organicmaps/downloader/ChunkTask.java | 2 +- .../downloader/CountrySuggestFragment.java | 7 +- .../downloader/DownloaderFragment.java | 1 + .../DownloaderToolbarController.java | 1 + .../organicmaps/editor/EditorFragment.java | 3 +- .../app/organicmaps/maplayer/SearchWheel.java | 3 +- .../routing/NavigationController.java | 16 +- .../routing/NavigationService.java | 8 +- .../app/organicmaps/search/SearchAdapter.java | 9 +- .../organicmaps/search/SearchFragment.java | 2 + .../search/SearchHistoryFragment.java | 6 - .../settings/BaseSettingsFragment.java | 4 +- .../settings/SettingsPrefsFragment.java | 7 +- .../settings/StoragePathFragment.java | 15 +- .../app/organicmaps/util/StorageUtils.java | 3 +- android/src/app/organicmaps/util/UiUtils.java | 45 ++--- android/src/app/organicmaps/util/Utils.java | 155 +++++++++++++----- .../widget/StackedButtonsDialog.java | 4 +- .../BookmarkColorDialogFragment.java | 2 + .../placepage/EditBookmarkFragment.java | 44 ++--- .../placepage/PlacePageBookmarkFragment.java | 2 +- .../widget/placepage/PlacePageController.java | 2 + .../PlacePageOpeningHoursFragment.java | 3 +- .../widget/placepage/PlacePageView.java | 6 +- .../placepage/PlacePageWikipediaFragment.java | 3 +- 38 files changed, 252 insertions(+), 138 deletions(-) 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 mDescriptionMaxLength) { description = (Spanned) new SpannableStringBuilder(description)