diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt index 3b2ddc572a..2a9f66aee4 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt @@ -4,7 +4,7 @@ import android.annotation.SuppressLint import android.content.Context import android.hardware.* import android.location.Location -import android.os.HandlerThread +import android.os.Looper import android.util.Log import com.google.android.gms.location.* import net.osmand.PlatformUtil @@ -43,7 +43,6 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve var lastKnownLocation: net.osmand.Location? = null private set - private val locationUpdateHandlerThread = HandlerThread("LocationProviderUpdateHandlerThread") private var fusedLocationProviderClient: FusedLocationProviderClient? = null private val locationRequest = LocationRequest().apply { interval = 1000 @@ -82,10 +81,6 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve fun updateCompassValue(value: Float) } - init { - locationUpdateHandlerThread.start() - } - @SuppressLint("MissingPermission") fun resumeAllUpdates() { if (AndroidUtils.isLocationPermissionAvailable(app) && fusedLocationProviderClient == null) { @@ -94,7 +89,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve try { fusedLocationProviderClient?.requestLocationUpdates( - locationRequest, locationCallback, locationUpdateHandlerThread.looper) + locationRequest, locationCallback, Looper.myLooper()) } catch (unlikely: SecurityException) { Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't request updates. $unlikely") } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt index bc0773b7e4..80d3e05098 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt @@ -38,7 +38,6 @@ class TelegramService : Service(), TelegramIncomingMessagesListener, private var updateWidgetHandler: Handler? = null private var updateWidgetThread = HandlerThread("WidgetUpdateServiceThread") - private var locationUpdateHandlerThread = HandlerThread("LocationUpdateServiceThread") // FusedLocationProviderClient - Main class for receiving location updates. private lateinit var fusedLocationProviderClient: FusedLocationProviderClient @@ -63,7 +62,6 @@ class TelegramService : Service(), TelegramIncomingMessagesListener, mHandlerThread.start() tracksHandlerThread.start() updateWidgetThread.start() - locationUpdateHandlerThread.start() updateShareInfoHandler = Handler(mHandlerThread.looper) updateTracksHandler = Handler(tracksHandlerThread.looper) updateWidgetHandler = Handler(updateWidgetThread.looper) @@ -168,7 +166,6 @@ class TelegramService : Service(), TelegramIncomingMessagesListener, tracksHandlerThread.quit() mHandlerThread.quit() updateWidgetThread.quit() - locationUpdateHandlerThread.quit() app().showLocationHelper.addOrUpdateStatusWidget(-1, false) usedBy = 0 @@ -201,7 +198,7 @@ class TelegramService : Service(), TelegramIncomingMessagesListener, // request location updates try { fusedLocationProviderClient.requestLocationUpdates( - locationRequest, locationCallback, locationUpdateHandlerThread.looper) + locationRequest, locationCallback, Looper.myLooper()) } catch (unlikely: SecurityException) { Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show() Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't request updates. $unlikely") diff --git a/OsmAnd/AndroidManifest-huawei.xml b/OsmAnd/AndroidManifest-huawei.xml index c71b7a3a93..f45fb81404 100644 --- a/OsmAnd/AndroidManifest-huawei.xml +++ b/OsmAnd/AndroidManifest-huawei.xml @@ -4,7 +4,7 @@ - \ No newline at end of file + diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index eb23647924..c757d455d2 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -202,6 +202,7 @@ dependencies { } implementation 'com.jaredrummler:colorpicker:1.1.0' implementation "org.bouncycastle:bcpkix-jdk15on:1.56" + implementation 'com.google.android.play:core:1.9.1' huaweiImplementation 'com.huawei.hms:iap:5.0.2.300' diff --git a/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java b/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java index 2abfc7aee5..5740e2b47b 100644 --- a/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java +++ b/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java @@ -1,7 +1,6 @@ package net.osmand.plus; import android.location.Location; -import android.os.HandlerThread; import android.os.Looper; import androidx.annotation.NonNull; @@ -14,7 +13,6 @@ import com.google.android.gms.location.LocationResult; import com.google.android.gms.location.LocationServices; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; -import com.google.android.gms.tasks.Tasks; import net.osmand.PlatformUtil; import net.osmand.plus.helpers.DayNightHelper; @@ -23,9 +21,6 @@ import net.osmand.plus.helpers.LocationServiceHelper; import org.apache.commons.logging.Log; import java.util.Collections; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; public class LocationServiceHelperImpl extends LocationServiceHelper { @@ -33,8 +28,6 @@ public class LocationServiceHelperImpl extends LocationServiceHelper { private final OsmandApplication app; - private final HandlerThread mHandlerThread = new HandlerThread("LocationServiceHelperThread"); - // FusedLocationProviderClient - Main class for receiving location updates. private final FusedLocationProviderClient fusedLocationProviderClient; @@ -49,7 +42,6 @@ public class LocationServiceHelperImpl extends LocationServiceHelper { public LocationServiceHelperImpl(@NonNull OsmandApplication app) { this.app = app; - mHandlerThread.start(); fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(app); @@ -104,7 +96,7 @@ public class LocationServiceHelperImpl extends LocationServiceHelper { // request location updates try { fusedLocationProviderClient.requestLocationUpdates( - fusedLocationRequest, fusedLocationCallback, mHandlerThread.getLooper()); + fusedLocationRequest, fusedLocationCallback, Looper.myLooper()); } catch (SecurityException e) { LOG.debug("Location service permission not granted"); throw e; diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java index 1482753b72..760b60599f 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java @@ -373,30 +373,22 @@ public class OsmAndLocationProvider implements SensorEventListener { public void addLocationListener(@NonNull OsmAndLocationListener listener) { if (!locationListeners.contains(listener)) { - List listeners = new ArrayList<>(locationListeners); - listeners.add(listener); - locationListeners = listeners; + locationListeners.add(listener); } } public void removeLocationListener(@NonNull OsmAndLocationListener listener) { - List listeners = new ArrayList<>(locationListeners); - listeners.remove(listener); - locationListeners = listeners; + locationListeners.remove(listener); } public void addCompassListener(@NonNull OsmAndCompassListener listener) { if (!compassListeners.contains(listener)) { - List listeners = new ArrayList<>(compassListeners); - listeners.add(listener); - compassListeners = listeners; + compassListeners.add(listener); } } public void removeCompassListener(@NonNull OsmAndCompassListener listener) { - List listeners = new ArrayList<>(compassListeners); - listeners.remove(listener); - compassListeners = listeners; + compassListeners.remove(listener); } @Nullable diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 165a9a9c07..8f89660c00 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -24,13 +24,6 @@ import android.view.View; import android.view.accessibility.AccessibilityManager; import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.multidex.MultiDex; -import androidx.multidex.MultiDexApplication; - import net.osmand.AndroidUtils; import net.osmand.FileUtils; import net.osmand.IndexConstants; @@ -53,7 +46,6 @@ import net.osmand.plus.api.SQLiteAPI; import net.osmand.plus.api.SQLiteAPIImpl; import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.dialogs.CrashBottomSheetDialogFragment; -import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment; import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadService; import net.osmand.plus.download.IndexItem; @@ -62,6 +54,7 @@ import net.osmand.plus.helpers.DayNightHelper; import net.osmand.plus.helpers.LocaleHelper; import net.osmand.plus.helpers.LocationServiceHelper; import net.osmand.plus.helpers.LockHelper; +import net.osmand.plus.helpers.RateUsHelper; import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.helpers.enums.DrivingRegion; import net.osmand.plus.helpers.enums.MetricsConstants; @@ -106,6 +99,12 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.multidex.MultiDex; +import androidx.multidex.MultiDexApplication; import btools.routingapp.BRouterServiceConnection; import btools.routingapp.IBRouterService; @@ -288,8 +287,8 @@ public class OsmandApplication extends MultiDexApplication { if (routingHelper != null) { routingHelper.getVoiceRouter().onApplicationTerminate(); } - if(RateUsBottomSheetDialogFragment.shouldShow(this)) { - osmandSettings.RATE_US_STATE.set(RateUsBottomSheetDialogFragment.RateUsState.IGNORED); + if(RateUsHelper.shouldShowRateDialog(this)) { + osmandSettings.RATE_US_STATE.set(RateUsHelper.RateUsState.IGNORED); } getNotificationHelper().removeNotifications(false); } diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 7adfd1a811..2273c91742 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -30,21 +30,6 @@ import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.core.app.ActivityCompat; -import androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback; -import androidx.core.content.ContextCompat; -import androidx.drawerlayout.widget.DrawerLayout; -import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentManager.BackStackEntry; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback; - import net.osmand.AndroidUtils; import net.osmand.GPXUtilities.GPXFile; import net.osmand.Location; @@ -87,7 +72,6 @@ import net.osmand.plus.dashboard.DashBaseFragment; import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.dialogs.CrashBottomSheetDialogFragment; import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment; -import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment; import net.osmand.plus.dialogs.SendAnalyticsBottomSheetDialogFragment; import net.osmand.plus.dialogs.WhatsNewDialogFragment; import net.osmand.plus.dialogs.XMasDialogFragment; @@ -102,6 +86,7 @@ import net.osmand.plus.helpers.DiscountHelper; import net.osmand.plus.helpers.IntentHelper; import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.LockHelper.LockUIAdapter; +import net.osmand.plus.helpers.RateUsHelper; import net.osmand.plus.helpers.ScrollHelper; import net.osmand.plus.helpers.ScrollHelper.OnScrollEventListener; import net.osmand.plus.importfiles.ImportHelper; @@ -170,6 +155,21 @@ import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.core.app.ActivityCompat; +import androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback; +import androidx.core.content.ContextCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentManager.BackStackEntry; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback; + import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID; public class MapActivity extends OsmandActionBarActivity implements DownloadEvents, @@ -731,9 +731,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven if (CrashBottomSheetDialogFragment.shouldShow(settings, this)) { SecondSplashScreenFragment.SHOW = false; CrashBottomSheetDialogFragment.showInstance(getSupportFragmentManager()); - } else if (RateUsBottomSheetDialogFragment.shouldShow(app)) { + } else if (RateUsHelper.shouldShowRateDialog(app)) { SecondSplashScreenFragment.SHOW = false; - RateUsBottomSheetDialogFragment.showInstance(getSupportFragmentManager()); + RateUsHelper.showRateDialog(this); } } } else { diff --git a/OsmAnd/src/net/osmand/plus/dialogs/DislikeOsmAndBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/DislikeOsmAndBottomSheetDialogFragment.java index 4cd7275db1..eaa1f067d1 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/DislikeOsmAndBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/DislikeOsmAndBottomSheetDialogFragment.java @@ -7,26 +7,26 @@ import android.net.Uri; import android.os.Bundle; import android.view.View; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.helpers.RateUsHelper; +import net.osmand.plus.helpers.RateUsHelper.RateUsState; + +import org.apache.commons.logging.Log; + import androidx.annotation.NonNull; import androidx.appcompat.view.ContextThemeWrapper; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.R; -import net.osmand.plus.base.MenuBottomSheetDialogFragment; -import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; -import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment.RateUsState; - -import org.apache.commons.logging.Log; - public class DislikeOsmAndBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { public static final String TAG = "DislikeOsmAndBottomSheetDialogFragment"; private static final Log LOG = PlatformUtil.getLog(DislikeOsmAndBottomSheetDialogFragment.class); - private RateUsState newRateUsState = RateUsState.IGNORED; + private RateUsHelper rateUsHelper; @Override public void createMenuItems(Bundle savedInstanceState) { @@ -35,6 +35,8 @@ public class DislikeOsmAndBottomSheetDialogFragment extends MenuBottomSheetDialo return; } + rateUsHelper = new RateUsHelper(); + final View titleView = View.inflate(new ContextThemeWrapper(context, themeRes), R.layout.dislike_title, null); final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder() .setCustomView(titleView) @@ -51,7 +53,7 @@ public class DislikeOsmAndBottomSheetDialogFragment extends MenuBottomSheetDialo protected void onDismissButtonClickAction() { OsmandApplication app = getMyApplication(); if (app != null) { - newRateUsState = RateUsState.DISLIKED_WITHOUT_MESSAGE; + rateUsHelper.updateState(RateUsState.DISLIKED_WITHOUT_MESSAGE); } } @@ -64,7 +66,7 @@ public class DislikeOsmAndBottomSheetDialogFragment extends MenuBottomSheetDialo protected void onRightBottomButtonClick() { OsmandApplication app = getMyApplication(); if (app != null) { - newRateUsState = RateUsState.DISLIKED_WITH_MESSAGE; + rateUsHelper.updateState(RateUsState.DISLIKED_WITH_MESSAGE); String email = getString(R.string.support_email); Intent sendEmail = new Intent(Intent.ACTION_SENDTO); sendEmail.setData(Uri.parse("mailto:" + email)); @@ -78,14 +80,7 @@ public class DislikeOsmAndBottomSheetDialogFragment extends MenuBottomSheetDialo public void onDismiss(@NonNull DialogInterface dialog) { super.onDismiss(dialog); FragmentActivity activity = getActivity(); - if (newRateUsState != null && activity != null && !activity.isChangingConfigurations()) { - OsmandApplication app = (OsmandApplication) activity.getApplication(); - OsmandSettings settings = app.getSettings(); - RateUsState newState = RateUsState.getNewState(app, newRateUsState); - settings.RATE_US_STATE.set(newState); - settings.NUMBER_OF_APP_STARTS_ON_DISLIKE_MOMENT.set(app.getAppInitializer().getNumberOfStarts()); - settings.LAST_DISPLAY_TIME.set(System.currentTimeMillis()); - } + rateUsHelper.storeRateResult(activity); } public static void showInstance(@NonNull FragmentManager fm) { diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialogFragment.java index 188031ea1d..67204cbbad 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialogFragment.java @@ -8,26 +8,26 @@ import android.os.Bundle; import android.view.ContextThemeWrapper; import android.view.View; -import androidx.annotation.NonNull; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; - import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.helpers.RateUsHelper; +import net.osmand.plus.helpers.RateUsHelper.RateUsState; import org.apache.commons.logging.Log; +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + public class RateUsBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { public static final String TAG = "RateUsBottomSheetDialogFragment"; private static final Log LOG = PlatformUtil.getLog(SendAnalyticsBottomSheetDialogFragment.class); - private static final long SIXTY_DAYS = 60 * 24 * 60 * 60 * 1000L; - private RateUsState newRateUsState = RateUsState.IGNORED; + private RateUsHelper rateUsHelper; @Override public void createMenuItems(Bundle savedInstanceState) { @@ -36,6 +36,8 @@ public class RateUsBottomSheetDialogFragment extends MenuBottomSheetDialogFragme return; } + rateUsHelper = new RateUsHelper(); + final View titleView = View.inflate(new ContextThemeWrapper(context, themeRes), R.layout.rate_us_title, null); final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder() .setCustomView(titleView) @@ -52,7 +54,7 @@ public class RateUsBottomSheetDialogFragment extends MenuBottomSheetDialogFragme protected void onDismissButtonClickAction() { FragmentManager fm = getFragmentManager(); if (fm != null) { - newRateUsState = null; + rateUsHelper.updateState(null); DislikeOsmAndBottomSheetDialogFragment.showInstance(fm); } } @@ -66,7 +68,7 @@ public class RateUsBottomSheetDialogFragment extends MenuBottomSheetDialogFragme protected void onRightBottomButtonClick() { OsmandApplication app = getMyApplication(); if (app != null) { - newRateUsState = RateUsState.LIKED; + rateUsHelper.updateState(RateUsState.LIKED); Uri uri = Uri.parse(Version.getUrlWithUtmRef(app, app.getPackageName())); try { Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); @@ -82,16 +84,7 @@ public class RateUsBottomSheetDialogFragment extends MenuBottomSheetDialogFragme public void onDismiss(@NonNull DialogInterface dialog) { super.onDismiss(dialog); FragmentActivity activity = getActivity(); - if (newRateUsState != null && activity != null && !activity.isChangingConfigurations()) { - OsmandApplication app = (OsmandApplication) activity.getApplication(); - OsmandSettings settings = app.getSettings(); - RateUsState newState = RateUsState.getNewState(app, newRateUsState); - settings.RATE_US_STATE.set(newState); - if (newState != RateUsState.LIKED) { - settings.NUMBER_OF_APP_STARTS_ON_DISLIKE_MOMENT.set(app.getAppInitializer().getNumberOfStarts()); - } - settings.LAST_DISPLAY_TIME.set(System.currentTimeMillis()); - } + rateUsHelper.storeRateResult(activity); } public static void showInstance(@NonNull FragmentManager fm) { @@ -105,56 +98,4 @@ public class RateUsBottomSheetDialogFragment extends MenuBottomSheetDialogFragme } } - public static boolean shouldShow(OsmandApplication app) { - long firstInstalledDays = app.getAppInitializer().getFirstInstalledDays(); - //Do not show dialog if not google play version or more than 350 days left from the first start - if (!Version.isGooglePlayEnabled() || firstInstalledDays > 350) { - return false; - } - OsmandSettings settings = app.getSettings(); - int numberOfStarts = app.getAppInitializer().getNumberOfStarts(); - RateUsState state = settings.RATE_US_STATE.get(); - switch (state) { - //Do not show anymore if liked - case LIKED: - case DISLIKED_OR_IGNORED_AGAIN: - return false; - //First dialog after 15 days from the first start or 100 starts - case INITIAL_STATE: - return firstInstalledDays > 15 || numberOfStarts > 100; - //Second dialog after 60 days or 50 starts from the first appearance (if ignored or disliked) - case IGNORED: - case DISLIKED_WITH_MESSAGE: - case DISLIKED_WITHOUT_MESSAGE: - int startsOnDislikeMoment = settings.NUMBER_OF_APP_STARTS_ON_DISLIKE_MOMENT.get(); - long lastDisplayTimeInMillis = settings.LAST_DISPLAY_TIME.get(); - long currentTime = System.currentTimeMillis(); - return currentTime - lastDisplayTimeInMillis > SIXTY_DAYS || numberOfStarts - startsOnDislikeMoment > 50; - } - return false; - } - - public enum RateUsState { - INITIAL_STATE, - IGNORED, - LIKED, - DISLIKED_WITH_MESSAGE, - DISLIKED_WITHOUT_MESSAGE, - DISLIKED_OR_IGNORED_AGAIN; - - public static RateUsState getNewState(OsmandApplication app, RateUsState requiredState) { - RateUsState currentState = app.getSettings().RATE_US_STATE.get(); - switch (requiredState) { - case INITIAL_STATE: - case LIKED: - case DISLIKED_OR_IGNORED_AGAIN: - return requiredState; - case IGNORED: - case DISLIKED_WITH_MESSAGE: - case DISLIKED_WITHOUT_MESSAGE: - return currentState == INITIAL_STATE ? requiredState : RateUsState.DISLIKED_OR_IGNORED_AGAIN; - } - return requiredState; - } - } } diff --git a/OsmAnd/src/net/osmand/plus/helpers/RateUsHelper.java b/OsmAnd/src/net/osmand/plus/helpers/RateUsHelper.java new file mode 100644 index 0000000000..29068ab46d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/RateUsHelper.java @@ -0,0 +1,157 @@ +package net.osmand.plus.helpers; + +import android.os.Build; + +import com.google.android.play.core.review.ReviewInfo; +import com.google.android.play.core.review.ReviewManager; +import com.google.android.play.core.review.ReviewManagerFactory; +import com.google.android.play.core.tasks.OnCompleteListener; +import com.google.android.play.core.tasks.Task; + +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.Version; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment; +import net.osmand.plus.settings.backend.OsmandSettings; + +import org.apache.commons.logging.Log; + +import java.lang.ref.WeakReference; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +public class RateUsHelper { + + private static final Log log = PlatformUtil.getLog(RateUsHelper.class); + private static final long SIXTY_DAYS = 60 * 24 * 60 * 60 * 1000L; + + private RateUsState rateUsState; + + public RateUsHelper() { + this.rateUsState = RateUsState.IGNORED; + } + + public void storeRateResult(FragmentActivity activity) { + storeRateResult(activity, rateUsState); + } + + private static void storeRateResult(FragmentActivity activity, RateUsState state) { + if (state != null && activity != null && !activity.isChangingConfigurations()) { + OsmandApplication app = (OsmandApplication) activity.getApplication(); + OsmandSettings settings = app.getSettings(); + RateUsState newState = RateUsState.getNewState(app, state); + settings.RATE_US_STATE.set(newState); + if (newState != RateUsState.LIKED) { + settings.NUMBER_OF_APP_STARTS_ON_DISLIKE_MOMENT.set(app.getAppInitializer().getNumberOfStarts()); + } + settings.LAST_DISPLAY_TIME.set(System.currentTimeMillis()); + } + } + + public void updateState(@Nullable RateUsState state) { + this.rateUsState = state; + } + + public static boolean shouldShowRateDialog(OsmandApplication app) { + long firstInstalledDays = app.getAppInitializer().getFirstInstalledDays(); + //Do not show dialog if not google play version or more than 350 days left from the first start + if (!Version.isGooglePlayEnabled() || firstInstalledDays > 350) { + return false; + } + OsmandSettings settings = app.getSettings(); + int numberOfStarts = app.getAppInitializer().getNumberOfStarts(); + RateUsState state = settings.RATE_US_STATE.get(); + switch (state) { + //Do not show anymore if liked + case LIKED: + case DISLIKED_OR_IGNORED_AGAIN: + return false; + //First dialog after 15 days from the first start or 100 starts + case INITIAL_STATE: + return firstInstalledDays > 15 || numberOfStarts > 100; + //Second dialog after 60 days or 50 starts from the first appearance (if ignored or disliked) + case IGNORED: + case DISLIKED_WITH_MESSAGE: + case DISLIKED_WITHOUT_MESSAGE: + int startsOnDislikeMoment = settings.NUMBER_OF_APP_STARTS_ON_DISLIKE_MOMENT.get(); + long lastDisplayTimeInMillis = settings.LAST_DISPLAY_TIME.get(); + long currentTime = System.currentTimeMillis(); + return currentTime - lastDisplayTimeInMillis > SIXTY_DAYS || numberOfStarts - startsOnDislikeMoment > 50; + } + return false; + } + + public static void showRateDialog(MapActivity mapActivity) { + boolean inAppReviewSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + if (inAppReviewSupported && Version.isGooglePlayInstalled(mapActivity.getMyApplication())) { + showInAppRateDialog(mapActivity); + } else { + RateUsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager()); + } + } + + private static void showInAppRateDialog(FragmentActivity activity) { + final ReviewManager reviewManager = ReviewManagerFactory.create(activity); + final WeakReference activityRef = new WeakReference<>(activity); + Task requestReview = reviewManager.requestReviewFlow(); + requestReview.addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + FragmentActivity activity = activityRef.get(); + if (activity != null) { + showInAppRateDialogInternal(reviewManager, activity, task.getResult()); + } + } else { + log.error(task.getException()); + } + } + }); + } + + private static void showInAppRateDialogInternal(ReviewManager reviewManager, FragmentActivity activity, ReviewInfo reviewInfo) { + Task reviewFlow = reviewManager.launchReviewFlow(activity, reviewInfo); + final WeakReference activityRef = new WeakReference<>(activity); + reviewFlow.addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + FragmentActivity activity = activityRef.get(); + if (activity != null) { + storeRateResult(activity, RateUsState.IGNORED); + } + } else { + log.error(task.getException()); + } + } + }); + } + + public enum RateUsState { + INITIAL_STATE, + IGNORED, + LIKED, + DISLIKED_WITH_MESSAGE, + DISLIKED_WITHOUT_MESSAGE, + DISLIKED_OR_IGNORED_AGAIN; + + public static RateUsState getNewState(OsmandApplication app, RateUsState requiredState) { + RateUsState currentState = app.getSettings().RATE_US_STATE.get(); + switch (requiredState) { + case INITIAL_STATE: + case LIKED: + case DISLIKED_OR_IGNORED_AGAIN: + return requiredState; + case IGNORED: + case DISLIKED_WITH_MESSAGE: + case DISLIKED_WITHOUT_MESSAGE: + return currentState == INITIAL_STATE ? requiredState : RateUsState.DISLIKED_OR_IGNORED_AGAIN; + } + return requiredState; + } + } + +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java index 32e045948d..96d6f9a8f4 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java @@ -1444,8 +1444,9 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm if (!compassUpdateAllowed) { return; } - final OsmandApplication app = getMyApplication(); - if (app != null && adapter != null) { + Activity activity = getActivity(); + if (activity != null && adapter != null) { + OsmandApplication app = (OsmandApplication) activity.getApplication(); app.runInUIThread(new Runnable() { @Override public void run() { diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index 627edb157d..3512de68bc 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -1002,6 +1002,7 @@ public class MeasurementEditingContext implements IRouteSettingsListener { pts.add(pt); } calculatedPairs++; + params.calculationProgressCallback.updateProgress(0); List originalRoute = route.getOriginalRoute(); if (Algorithms.isEmpty(originalRoute)) { originalRoute = Collections.singletonList(RoutePlannerFrontEnd.generateStraightLineSegment( @@ -1011,7 +1012,6 @@ public class MeasurementEditingContext implements IRouteSettingsListener { application.runInUIThread(new Runnable() { @Override public void run() { - params.calculationProgressCallback.updateProgress(0); updateSegmentsForSnap(true, false); progressListener.refresh(); RouteCalculationParams params = getParams(false); diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteRecalculationHelper.java b/OsmAnd/src/net/osmand/plus/routing/RouteRecalculationHelper.java index a4348e75c9..175003fe18 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteRecalculationHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteRecalculationHelper.java @@ -232,17 +232,11 @@ class RouteRecalculationHelper { } void startProgress(final RouteCalculationParams params) { - app.runInUIThread(new Runnable() { - - @Override - public void run() { - if (params.calculationProgressCallback != null) { - params.calculationProgressCallback.start(); - } else if (progressRoute != null) { - progressRoute.start(); - } - } - }); + if (params.calculationProgressCallback != null) { + params.calculationProgressCallback.start(); + } else if (progressRoute != null) { + progressRoute.start(); + } } void updateProgress(final RouteCalculationParams params) { diff --git a/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java index 2b70cbe1b8..08da774f27 100644 --- a/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java @@ -237,12 +237,7 @@ public class TransportRoutingHelper { private void startProgress(final TransportRouteCalculationParams params) { final TransportRouteCalculationProgressCallback progressRoute = this.progressRoute; if (progressRoute != null) { - app.runInUIThread(new Runnable() { - @Override - public void run() { - progressRoute.start(); - } - }, 300); + progressRoute.start(); } setCurrentRoute(-1); } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 50c55e316c..e69d9b87e9 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -11,10 +11,6 @@ import android.net.NetworkInfo; import android.os.Build; import android.os.Environment; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.util.Pair; - import net.osmand.FileUtils; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; @@ -35,8 +31,8 @@ import net.osmand.plus.api.SettingsAPI; import net.osmand.plus.api.SettingsAPI.SettingsEditor; import net.osmand.plus.api.SettingsAPIImpl; import net.osmand.plus.audionotes.NotesSortByMode; -import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment.RateUsState; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; +import net.osmand.plus.helpers.RateUsHelper.RateUsState; import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.enums.AngularConstants; import net.osmand.plus.helpers.enums.AutoZoomMap; @@ -80,6 +76,10 @@ import java.util.Map; import java.util.Set; import java.util.StringTokenizer; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.util.Pair; + import static net.osmand.aidlapi.OsmAndCustomizationConstants.CONFIGURE_MAP_ITEM_ID_SCHEME; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_ITEM_ID_SCHEME; import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_ACTIONS;