diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml
index 02776da9a6..0ff1017482 100644
--- a/OsmAnd/AndroidManifest.xml
+++ b/OsmAnd/AndroidManifest.xml
@@ -901,5 +901,8 @@
android:name=".profiles.EditProfileActivity"
android:label="Application profiles"/>
-
+
+
+
diff --git a/OsmAnd/res/drawable-hdpi/img_get_feedback.webp b/OsmAnd/res/drawable-hdpi/img_get_feedback.webp
new file mode 100644
index 0000000000..54275e2b39
Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/img_get_feedback.webp differ
diff --git a/OsmAnd/res/drawable-mdpi/img_get_feedback.webp b/OsmAnd/res/drawable-mdpi/img_get_feedback.webp
new file mode 100644
index 0000000000..c7f9d51f9f
Binary files /dev/null and b/OsmAnd/res/drawable-mdpi/img_get_feedback.webp differ
diff --git a/OsmAnd/res/drawable-xhdpi/img_get_feedback.webp b/OsmAnd/res/drawable-xhdpi/img_get_feedback.webp
new file mode 100644
index 0000000000..7619d802b5
Binary files /dev/null and b/OsmAnd/res/drawable-xhdpi/img_get_feedback.webp differ
diff --git a/OsmAnd/res/drawable-xxhdpi/img_get_feedback.webp b/OsmAnd/res/drawable-xxhdpi/img_get_feedback.webp
new file mode 100644
index 0000000000..07c1552604
Binary files /dev/null and b/OsmAnd/res/drawable-xxhdpi/img_get_feedback.webp differ
diff --git a/OsmAnd/res/drawable-xxxhdpi/img_get_feedback.webp b/OsmAnd/res/drawable-xxxhdpi/img_get_feedback.webp
new file mode 100644
index 0000000000..73dfce7b57
Binary files /dev/null and b/OsmAnd/res/drawable-xxxhdpi/img_get_feedback.webp differ
diff --git a/OsmAnd/res/drawable/ripple_solid_dark.xml b/OsmAnd/res/drawable/ripple_solid_dark.xml
index 45178468da..9e9e6a0cce 100644
--- a/OsmAnd/res/drawable/ripple_solid_dark.xml
+++ b/OsmAnd/res/drawable/ripple_solid_dark.xml
@@ -1,5 +1,5 @@
+ android:color="@color/active_buttons_and_links_pressed_dark">
-
diff --git a/OsmAnd/res/drawable/ripple_solid_light.xml b/OsmAnd/res/drawable/ripple_solid_light.xml
index 69270d496e..b390b7cce7 100644
--- a/OsmAnd/res/drawable/ripple_solid_light.xml
+++ b/OsmAnd/res/drawable/ripple_solid_light.xml
@@ -1,5 +1,5 @@
+ android:color="@color/active_buttons_and_links_pressed_light">
-
diff --git a/OsmAnd/res/layout/bottom_sheet_item_description_long.xml b/OsmAnd/res/layout/bottom_sheet_item_description_long.xml
index 72c2da3171..d841ca0430 100644
--- a/OsmAnd/res/layout/bottom_sheet_item_description_long.xml
+++ b/OsmAnd/res/layout/bottom_sheet_item_description_long.xml
@@ -11,4 +11,5 @@
android:paddingRight="@dimen/content_padding"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
+ android:linksClickable="true"
tools:text="Some long description"/>
diff --git a/OsmAnd/res/layout/crash_title.xml b/OsmAnd/res/layout/crash_title.xml
new file mode 100644
index 0000000000..7dea5a337d
--- /dev/null
+++ b/OsmAnd/res/layout/crash_title.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/dislike_title.xml b/OsmAnd/res/layout/dislike_title.xml
new file mode 100644
index 0000000000..a5fb49608b
--- /dev/null
+++ b/OsmAnd/res/layout/dislike_title.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/make_better_title.xml b/OsmAnd/res/layout/make_better_title.xml
new file mode 100644
index 0000000000..bd3d57e129
--- /dev/null
+++ b/OsmAnd/res/layout/make_better_title.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/privacy_settings_layout.xml b/OsmAnd/res/layout/privacy_settings_layout.xml
new file mode 100644
index 0000000000..a6587a6919
--- /dev/null
+++ b/OsmAnd/res/layout/privacy_settings_layout.xml
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/rate_us_title.xml b/OsmAnd/res/layout/rate_us_title.xml
new file mode 100644
index 0000000000..9090a10b45
--- /dev/null
+++ b/OsmAnd/res/layout/rate_us_title.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/values/colors.xml b/OsmAnd/res/values/colors.xml
index e0d24ee9d8..cc70bf2be5 100644
--- a/OsmAnd/res/values/colors.xml
+++ b/OsmAnd/res/values/colors.xml
@@ -491,7 +491,6 @@
#dcdcdc
#EFEFEF
#ababab
- #505050
#727272
#727272
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 0fa36ba6fa..6c33f9bd58 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -11,6 +11,23 @@
Thx - Hardy
-->
+ Please give us 30 seconds, share feedback and rate our work on Google Play.
+ Rate
+ Privacy Policy
+ Help us make OsmAnd better!
+ Allow OsmAnd to collect and process anonymous application usage data. We do not collect or store data about your location, or about the locations that you view on the map.\n\nYou can always change your selection in Settings > Privacy and Security.
+ Choose what type of data you want to share:
+ Downloaded Maps
+ Visited screens
+ Colleted Data
+ List of data you want to share with OsmAnd.
+ We collect this data to understand the maps of which regions and countries are the most popular.
+ We collect this data to understand the most popular features of OsmAnd.
+ By clicking \"Allow\" you agree with our %1$s
+ Privacy and Security
+ Choose your data for sharing with us
+ No, thank you
+ Allow
Profile Name
Navigation Type
Taxi
diff --git a/OsmAnd/res/xml/settings_pref.xml b/OsmAnd/res/xml/settings_pref.xml
index 8f9e0c2fcc..22e47e3773 100644
--- a/OsmAnd/res/xml/settings_pref.xml
+++ b/OsmAnd/res/xml/settings_pref.xml
@@ -4,5 +4,6 @@
+
diff --git a/OsmAnd/src/net/osmand/plus/AnalyticsHelper.java b/OsmAnd/src/net/osmand/plus/AnalyticsHelper.java
index 9bbba55b9b..e906d7b9bb 100644
--- a/OsmAnd/src/net/osmand/plus/AnalyticsHelper.java
+++ b/OsmAnd/src/net/osmand/plus/AnalyticsHelper.java
@@ -49,10 +49,14 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
private final static String DATABASE_NAME = "analytics";
private final static int DATABASE_VERSION = 1;
- private final static String TABLE_NAME = "events";
+ private final static String TABLE_NAME = "app_events";
private final static String COL_DATE = "date";
+ private final static String COL_TYPE = "event_type";
private final static String COL_EVENT = "event";
+ public final static int EVENT_TYPE_APP_USAGE = 1;
+ public final static int EVENT_TYPE_MAP_DOWNLOAD = 2;
+
private OsmandApplication ctx;
private String insertEventScript;
private long lastSubmittedTime;
@@ -62,6 +66,7 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
private static class AnalyticsItem {
long date;
+ int type;
String event;
}
@@ -74,7 +79,7 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
AnalyticsHelper(OsmandApplication ctx) {
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
this.ctx = ctx;
- insertEventScript = "INSERT INTO " + TABLE_NAME + " VALUES (?, ?)";
+ insertEventScript = "INSERT INTO " + TABLE_NAME + " VALUES (?, ?, ?)";
submitCollectedDataAsync();
}
@@ -84,7 +89,7 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
}
private void createTable(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + COL_DATE + " long, " + COL_EVENT + " text )");
+ db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + COL_DATE + " long, " + COL_TYPE + " int, " + COL_EVENT + " text )");
}
@Override
@@ -108,7 +113,7 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
return res;
}
- private void clearDB( long finishDate) {
+ private void clearDB(long finishDate) {
SQLiteDatabase db = getWritableDatabase();
if (db != null && db.isOpen()) {
try {
@@ -123,11 +128,18 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
if (ctx.getSettings().isInternetConnectionAvailable()) {
long collectedRowsCount = getCollectedRowsCount();
if (collectedRowsCount > DATA_PARCEL_SIZE) {
- if (submittingTask == null || submittingTask.isDone()) {
+ final List allowedTypes = new ArrayList<>();
+ if (ctx.getSettings().SEND_ANONYMOUS_MAP_DOWNLOADS_DATA.get()) {
+ allowedTypes.add(EVENT_TYPE_MAP_DOWNLOAD);
+ }
+ if (ctx.getSettings().SEND_ANONYMOUS_APP_USAGE_DATA.get()) {
+ allowedTypes.add(EVENT_TYPE_APP_USAGE);
+ }
+ if ((submittingTask == null || submittingTask.isDone()) && allowedTypes.size() > 0) {
submittingTask = executor.submit(new Runnable() {
@Override
public void run() {
- submitCollectedData();
+ submitCollectedData(allowedTypes);
}
});
return true;
@@ -139,17 +151,19 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
@SuppressLint("HardwareIds")
- private boolean submitCollectedData() {
+ private void submitCollectedData(List allowedTypes) {
List data = collectRecordedData();
for (AnalyticsData d : data) {
if (d.items != null && d.items.size() > 0) {
try {
JSONArray jsonItemsArray = new JSONArray();
for (AnalyticsItem item : d.items) {
- JSONObject jsonItem = new JSONObject();
- jsonItem.put(JSON_DATE, item.date);
- jsonItem.put(JSON_EVENT, item.event);
- jsonItemsArray.put(jsonItem);
+ if (allowedTypes.contains(item.type)) {
+ JSONObject jsonItem = new JSONObject();
+ jsonItem.put(JSON_DATE, item.date);
+ jsonItem.put(JSON_EVENT, item.event);
+ jsonItemsArray.put(jsonItem);
+ }
}
Map additionalData = new LinkedHashMap();
@@ -172,16 +186,15 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
InputStream inputStream = new ByteArrayInputStream(jsonStr.getBytes());
String res = AndroidNetworkUtils.uploadFile(ANALYTICS_UPLOAD_URL, inputStream, ANALYTICS_FILE_NAME, true, additionalData);
if (res != null) {
- return false;
+ return;
}
} catch (Exception e) {
LOG.error(e);
- return false;
+ return;
}
clearDB(d.finishDate);
}
}
- return true;
}
private List collectRecordedData() {
@@ -198,7 +211,7 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
}
private void collectDBData(SQLiteDatabase db, List data) {
- Cursor query = db.rawQuery("SELECT " + COL_DATE + "," + COL_EVENT + " FROM " + TABLE_NAME + " ORDER BY " + COL_DATE + " ASC", null);
+ Cursor query = db.rawQuery("SELECT " + COL_DATE + "," + COL_TYPE + "," + COL_EVENT + " FROM " + TABLE_NAME + " ORDER BY " + COL_DATE + " ASC", null);
List items = new ArrayList<>();
int itemsCounter = 0;
long startDate = Long.MAX_VALUE;
@@ -208,7 +221,8 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
AnalyticsItem item = new AnalyticsItem();
long date = query.getLong(0);
item.date = date;
- item.event = query.getString(1);
+ item.type = query.getInt(1);
+ item.event = query.getString(2);
items.add(item);
itemsCounter++;
@@ -244,11 +258,11 @@ public class AnalyticsHelper extends SQLiteOpenHelper {
query.close();
}
- public void addEvent(String event) {
+ public void addEvent(String event, int type) {
SQLiteDatabase db = getWritableDatabase();
if (db != null && db.isOpen()) {
try {
- db.execSQL(insertEventScript, new Object[]{System.currentTimeMillis(), event});
+ db.execSQL(insertEventScript, new Object[]{System.currentTimeMillis(), type, event});
} finally {
db.close();
}
diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java
index e1c69f6e9e..7d374dfa29 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java
@@ -47,7 +47,7 @@ import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.api.SQLiteAPI;
import net.osmand.plus.api.SQLiteAPIImpl;
import net.osmand.plus.base.MapViewTrackingUtilities;
-import net.osmand.plus.dialogs.ErrorBottomSheetDialog;
+import net.osmand.plus.dialogs.CrashBottomSheetDialogFragment;
import net.osmand.plus.dialogs.RateUsBottomSheetDialog;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.download.IndexItem;
@@ -85,7 +85,8 @@ import btools.routingapp.BRouterServiceConnection;
import btools.routingapp.IBRouterService;
public class OsmandApplication extends MultiDexApplication {
- public static final String EXCEPTION_PATH = "exception.log";
+ public static final String EXCEPTION_PATH = "exception.log";
+ public static final String OSMAND_PRIVACY_POLICY_URL = "https://osmand.net/help-online/privacy-policy";
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmandApplication.class);
final AppInitializer appInitializer = new AppInitializer(this);
@@ -942,9 +943,7 @@ public class OsmandApplication extends MultiDexApplication {
public void logEvent(String event) {
try {
- if (osmandSettings.SEND_ANONYMOUS_APP_USAGE_DATA.get()) {
- analyticsHelper.addEvent(event);
- }
+ analyticsHelper.addEvent(event, AnalyticsHelper.EVENT_TYPE_APP_USAGE);
} catch (Exception e) {
LOG.error(e);
}
@@ -952,9 +951,7 @@ public class OsmandApplication extends MultiDexApplication {
public void logMapDownloadEvent(String event, IndexItem item) {
try {
- if (osmandSettings.SEND_ANONYMOUS_MAP_DOWNLOADS_DATA.get()) {
- analyticsHelper.addEvent("map_download_" + event + ": " + item.getFileName());
- }
+ analyticsHelper.addEvent("map_download_" + event + ": " + item.getFileName(), AnalyticsHelper.EVENT_TYPE_MAP_DOWNLOAD);
} catch (Exception e) {
LOG.error(e);
}
@@ -962,9 +959,7 @@ public class OsmandApplication extends MultiDexApplication {
public void logMapDownloadEvent(String event, IndexItem item, long time) {
try {
- if (osmandSettings.SEND_ANONYMOUS_MAP_DOWNLOADS_DATA.get()) {
- analyticsHelper.addEvent("map_download_" + event + ": " + item.getFileName() + " in " + time + " msec");
- }
+ analyticsHelper.addEvent("map_download_" + event + ": " + item.getFileName() + " in " + time + " msec", AnalyticsHelper.EVENT_TYPE_MAP_DOWNLOAD);
} catch (Exception e) {
LOG.error(e);
}
@@ -1009,7 +1004,7 @@ public class OsmandApplication extends MultiDexApplication {
text.append("\nApk Version : ").append(info.versionName).append(" ").append(info.versionCode);
}
} catch (PackageManager.NameNotFoundException e) {
- PlatformUtil.getLog(ErrorBottomSheetDialog.class).error("", e);
+ PlatformUtil.getLog(CrashBottomSheetDialogFragment.class).error("", e);
}
intent.putExtra(Intent.EXTRA_TEXT, text.toString());
Intent chooserIntent = Intent.createChooser(intent, getString(R.string.send_report));
diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
index 3c513469ab..49df65dd53 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
@@ -1060,6 +1060,9 @@ public class OsmandSettings {
public final OsmandPreference DO_NOT_USE_ANIMATIONS = new BooleanPreference("do_not_use_animations", false).makeGlobal().cache();
public final OsmandPreference SEND_ANONYMOUS_MAP_DOWNLOADS_DATA = new BooleanPreference("send_anonymous_map_downloads_data", false).makeGlobal().cache();
public final OsmandPreference SEND_ANONYMOUS_APP_USAGE_DATA = new BooleanPreference("send_anonymous_app_usage_data", false).makeGlobal().cache();
+ public final OsmandPreference SEND_ANONYMOUS_DATA_REQUEST_PROCESSED = new BooleanPreference("send_anonymous_data_request_processed", false).makeGlobal().cache();
+ public final OsmandPreference SEND_ANONYMOUS_DATA_REQUESTS_COUNT = new IntPreference("send_anonymous_data_requests_count", 0).makeGlobal().cache();
+ public final OsmandPreference SEND_ANONYMOUS_DATA_LAST_REQUEST_NS = new IntPreference("send_anonymous_data_last_request_ns", -1).makeGlobal().cache();
public final OsmandPreference MAP_EMPTY_STATE_ALLOWED = new BooleanPreference("map_empty_state_allowed", true).makeGlobal().cache();
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index 6cad542be5..3f56a6fac6 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -83,7 +83,9 @@ import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.chooseplan.OsmLiveCancelledDialog;
import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.dashboard.DashboardOnMap.DashboardType;
-import net.osmand.plus.dialogs.ErrorBottomSheetDialog;
+import net.osmand.plus.dialogs.CrashBottomSheetDialogFragment;
+import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment;
+import net.osmand.plus.dialogs.SendAnalyticsBottomSheetDialogFragment;
import net.osmand.plus.dialogs.RateUsBottomSheetDialog;
import net.osmand.plus.dialogs.WhatsNewDialogFragment;
import net.osmand.plus.dialogs.XMasDialogFragment;
@@ -680,12 +682,12 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
if (settings.SHOW_DASHBOARD_ON_START.get()) {
dashboardOnMap.setDashboardVisibility(true, DashboardOnMap.staticVisibleType);
} else {
- if (ErrorBottomSheetDialog.shouldShow(settings, this)) {
+ if (CrashBottomSheetDialogFragment.shouldShow(settings, this)) {
SecondSplashScreenFragment.SHOW = false;
- new ErrorBottomSheetDialog().show(getSupportFragmentManager(), "dialog");
- } else if (RateUsBottomSheetDialog.shouldShow(app)) {
+ CrashBottomSheetDialogFragment.showInstance(getSupportFragmentManager());
+ } else if (RateUsBottomSheetDialogFragment.shouldShow(app)) {
SecondSplashScreenFragment.SHOW = false;
- new RateUsBottomSheetDialog().show(getSupportFragmentManager(), "dialog");
+ RateUsBottomSheetDialogFragment.showInstance(getSupportFragmentManager());
}
}
} else {
@@ -860,6 +862,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
FirstUsageWelcomeFragment.TAG).commitAllowingStateLoss();
} else if (!isFirstScreenShowing() && OsmLiveCancelledDialog.shouldShowDialog(app)) {
OsmLiveCancelledDialog.showInstance(getSupportFragmentManager());
+ } else if (SendAnalyticsBottomSheetDialogFragment.shouldShowDialog(app)) {
+ SendAnalyticsBottomSheetDialogFragment.showInstance(app, getSupportFragmentManager());
}
FirstUsageWelcomeFragment.SHOW = false;
if (isFirstScreenShowing() && (!settings.SHOW_OSMAND_WELCOME_SCREEN.get() || !showOsmAndWelcomeScreen)) {
diff --git a/OsmAnd/src/net/osmand/plus/activities/PrivacyAndSecurityActivity.java b/OsmAnd/src/net/osmand/plus/activities/PrivacyAndSecurityActivity.java
new file mode 100644
index 0000000000..ce8e1da09c
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/activities/PrivacyAndSecurityActivity.java
@@ -0,0 +1,90 @@
+package net.osmand.plus.activities;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v7.widget.SwitchCompat;
+import android.support.v7.widget.Toolbar;
+import android.util.TypedValue;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.CompoundButton;
+
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.R;
+
+public class PrivacyAndSecurityActivity extends OsmandActionBarActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ OsmandApplication app = getMyApplication();
+ int themeId = !app.getSettings().isLightContent() ? R.style.OsmandDarkTheme_NoActionbar : R.style.OsmandLightTheme_NoActionbar;
+ setTheme(themeId);
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.privacy_settings_layout);
+ Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
+ tb.setTitle(R.string.settings_privacy_and_security);
+
+ tb.setClickable(true);
+ tb.setNavigationIcon(((OsmandApplication) getApplication()).getUIUtilities().getIcon(R.drawable.ic_arrow_back));
+ tb.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
+ tb.setBackgroundColor(getResources().getColor(resolveResourceId(this, R.attr.pstsTabBackground)));
+ tb.setTitleTextColor(getResources().getColor(resolveResourceId(this, R.attr.pstsTextColor)));
+ tb.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(final View v) {
+ finish();
+ }
+ });
+
+ View downloadedMapsContainer = findViewById(R.id.downloaded_maps_container);
+ final SwitchCompat downloadedMapsButton = (SwitchCompat) findViewById(R.id.downloaded_maps_button);
+ downloadedMapsButton.setChecked(app.getSettings().SEND_ANONYMOUS_MAP_DOWNLOADS_DATA.get());
+ downloadedMapsButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ OsmandApplication app = getMyApplication();
+ app.getSettings().SEND_ANONYMOUS_MAP_DOWNLOADS_DATA.set(isChecked);
+ }
+ });
+ downloadedMapsContainer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ downloadedMapsButton.setChecked(!downloadedMapsButton.isChecked());
+ }
+ });
+
+ View visitedScreensContainer = findViewById(R.id.visited_screens_container);
+ final SwitchCompat visitedScreensButton = (SwitchCompat) findViewById(R.id.visited_screens_button);
+ visitedScreensButton.setChecked(app.getSettings().SEND_ANONYMOUS_APP_USAGE_DATA.get());
+ visitedScreensButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ OsmandApplication app = getMyApplication();
+ app.getSettings().SEND_ANONYMOUS_APP_USAGE_DATA.set(isChecked);
+ }
+ });
+ visitedScreensContainer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ visitedScreensButton.setChecked(!visitedScreensButton.isChecked());
+ }
+ });
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int itemId = item.getItemId();
+ switch (itemId) {
+ case android.R.id.home:
+ finish();
+ return true;
+ }
+ return false;
+ }
+
+ private int resolveResourceId(final Activity activity, final int attr) {
+ final TypedValue typedvalueattr = new TypedValue();
+ activity.getTheme().resolveAttribute(attr, typedvalueattr, true);
+ return typedvalueattr.resourceId;
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java
index db7df49a1c..7fc3caab0b 100644
--- a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java
@@ -30,6 +30,7 @@ public class SettingsActivity extends SettingsBaseActivity {
private Preference routing;
private Preference subscription;
private Preference profiles;
+ private Preference privacy;
@Override
@@ -46,6 +47,8 @@ public class SettingsActivity extends SettingsBaseActivity {
profiles.setOnPreferenceClickListener(this);
subscription = (Preference) screen.findPreference("subscription_settings");
subscription.setOnPreferenceClickListener(this);
+ privacy = (Preference) screen.findPreference("privacy_and_security");
+ privacy.setOnPreferenceClickListener(this);
getToolbar().setTitle(Version.getFullVersion(getMyApplication()));
@@ -103,6 +106,10 @@ public class SettingsActivity extends SettingsBaseActivity {
intent.putExtra(OsmLiveActivity.SHOW_SETTINGS_ONLY_INTENT_PARAM, true);
startActivity(intent);
return true;
+ } else if (preference == privacy) {
+ Intent intent = new Intent(this, PrivacyAndSecurityActivity.class);
+ startActivity(intent);
+ return true;
} else {
super.onPreferenceClick(preference);
}
diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java
index 35bd35a350..c6ff3339ab 100644
--- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java
@@ -43,6 +43,8 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
protected boolean nightMode;
protected int themeRes;
+ protected View dismissButton;
+ protected View rightButton;
private LinearLayout itemsContainer;
@@ -85,8 +87,8 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
inflateMenuItems();
- View dismissButton = mainView.findViewById(R.id.dismiss_button);
- setupDialogButton(dismissButton, DialogButtonType.STROKED, getDismissButtonTextId());
+ dismissButton = mainView.findViewById(R.id.dismiss_button);
+ setupDialogButton(dismissButton, getDismissByttonType(), getDismissButtonTextId());
dismissButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -100,8 +102,8 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
int rightBottomButtonTextId = getRightBottomButtonTextId();
if (rightBottomButtonTextId != DEFAULT_VALUE) {
mainView.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE);
- View rightButton = mainView.findViewById(R.id.right_bottom_button);
- setupDialogButton(rightButton, DialogButtonType.PRIMARY, rightBottomButtonTextId);
+ rightButton = mainView.findViewById(R.id.right_bottom_button);
+ setupDialogButton(rightButton, getRightBottomByttonType(), rightBottomButtonTextId);
rightButton.setVisibility(View.VISIBLE);
rightButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -111,6 +113,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
});
}
}
+ updateBottomButtons();
setupHeightAndBackground(mainView);
return mainView;
}
@@ -283,6 +286,10 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
dismissButtonStringRes = stringRes;
}
+ protected DialogButtonType getDismissByttonType() {
+ return DialogButtonType.SECONDARY;
+ }
+
protected void onDismissButtonClickAction() {
}
@@ -292,10 +299,35 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
return DEFAULT_VALUE;
}
+ protected DialogButtonType getRightBottomByttonType() {
+ return DialogButtonType.PRIMARY;
+ }
+
protected void onRightBottomButtonClick() {
}
+ protected boolean isDismissButtonEnabled() {
+ return true;
+ }
+
+ protected boolean isRightBottomButtonEnabled() {
+ return true;
+ }
+
+ protected void updateBottomButtons() {
+ if (dismissButton != null) {
+ boolean enabled = isDismissButtonEnabled();
+ dismissButton.setEnabled(enabled);
+ dismissButton.findViewById(R.id.button_text).setEnabled(enabled);
+ }
+ if (rightButton != null) {
+ boolean enabled = isRightBottomButtonEnabled();
+ rightButton.setEnabled(enabled);
+ rightButton.findViewById(R.id.button_text).setEnabled(enabled);
+ }
+ }
+
@ColorRes
protected int getBgColorId() {
return nightMode ? R.color.bg_color_dark : R.color.bg_color_light;
diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemTitleWithDescrAndButton.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemTitleWithDescrAndButton.java
index fc347554fd..9b17400b29 100644
--- a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemTitleWithDescrAndButton.java
+++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemTitleWithDescrAndButton.java
@@ -35,6 +35,7 @@ public class BottomSheetItemTitleWithDescrAndButton extends BottomSheetItemWithD
CharSequence description,
@ColorRes int descriptionColorId,
int descriptionMaxLines,
+ boolean descriptionLinksClickable,
String buttonTitle,
View.OnClickListener onButtonClickListener,
Drawable leftCompoundDrawable,
@@ -51,7 +52,8 @@ public class BottomSheetItemTitleWithDescrAndButton extends BottomSheetItemWithD
titleColorId,
description,
descriptionColorId,
- descriptionMaxLines);
+ descriptionMaxLines,
+ descriptionLinksClickable);
this.buttonTitle = buttonTitle;
this.onButtonClickListener = onButtonClickListener;
this.leftCompoundDrawable = leftCompoundDrawable;
@@ -125,6 +127,7 @@ public class BottomSheetItemTitleWithDescrAndButton extends BottomSheetItemWithD
description,
descriptionColorId,
descriptionMaxLines,
+ descriptionLinksClickable,
buttonTitle,
onButtonClickListener,
leftCompoundDrawable,
diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java
index 7722438cdb..4ad4613034 100644
--- a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java
+++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java
@@ -37,6 +37,7 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri
CharSequence description,
@ColorRes int descriptionColorId,
int descriptionMaxLines,
+ boolean descriptionLinksClickable,
boolean checked,
ColorStateList buttonTintList,
OnCheckedChangeListener onCheckedChangeListener) {
@@ -51,7 +52,8 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri
titleColorId,
description,
descriptionColorId,
- descriptionMaxLines);
+ descriptionMaxLines,
+ descriptionLinksClickable);
this.checked = checked;
this.buttonTintList = buttonTintList;
this.onCheckedChangeListener = onCheckedChangeListener;
@@ -109,6 +111,7 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri
description,
descriptionColorId,
descriptionMaxLines,
+ descriptionLinksClickable,
checked,
buttonTintList,
onCheckedChangeListener);
diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithDescription.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithDescription.java
index fa26be10e7..ae08050abf 100644
--- a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithDescription.java
+++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithDescription.java
@@ -4,6 +4,7 @@ import android.graphics.drawable.Drawable;
import android.support.annotation.ColorRes;
import android.support.annotation.LayoutRes;
import android.support.v4.content.ContextCompat;
+import android.text.method.LinkMovementMethod;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
@@ -17,6 +18,7 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem {
@ColorRes
private int descriptionColorId = INVALID_ID;
private int descriptionMaxLines = INVALID_VALUE;
+ private boolean descriptionLinksClickable = false;
private TextView descriptionTv;
@@ -31,11 +33,13 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem {
@ColorRes int titleColorId,
CharSequence description,
@ColorRes int descriptionColorId,
- int descriptionMaxLines) {
+ int descriptionMaxLines,
+ boolean descriptionLinksClickable) {
super(customView, layoutId, tag, disabled, onClickListener, position, icon, title, titleColorId);
this.description = description;
this.descriptionColorId = descriptionColorId;
this.descriptionMaxLines = descriptionMaxLines;
+ this.descriptionLinksClickable = descriptionLinksClickable;
}
protected BottomSheetItemWithDescription() {
@@ -52,6 +56,17 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem {
descriptionTv.setMaxLines(maxLines);
}
+ public void setDescriptionLinksClickable(boolean descriptionLinksClickable) {
+ this.descriptionLinksClickable = descriptionLinksClickable;
+ if (descriptionTv != null) {
+ if (descriptionLinksClickable) {
+ descriptionTv.setMovementMethod(LinkMovementMethod.getInstance());
+ } else {
+ descriptionTv.setMovementMethod(null);
+ }
+ }
+ }
+
@Override
public void inflate(OsmandApplication app, ViewGroup container, boolean nightMode) {
super.inflate(app, container, nightMode);
@@ -64,6 +79,9 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem {
if (descriptionMaxLines != INVALID_VALUE) {
descriptionTv.setMaxLines(descriptionMaxLines);
}
+ if (descriptionLinksClickable) {
+ descriptionTv.setMovementMethod(LinkMovementMethod.getInstance());
+ }
}
}
@@ -73,6 +91,7 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem {
@ColorRes
protected int descriptionColorId = INVALID_ID;
protected int descriptionMaxLines = INVALID_POSITION;
+ protected boolean descriptionLinksClickable = false;
public Builder setDescription(CharSequence description) {
this.description = description;
@@ -89,6 +108,10 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem {
return this;
}
+ public void setDescriptionLinksClickable(boolean descriptionLinksClickable) {
+ this.descriptionLinksClickable = descriptionLinksClickable;
+ }
+
public BottomSheetItemWithDescription create() {
return new BottomSheetItemWithDescription(customView,
layoutId,
@@ -101,7 +124,8 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem {
titleColorId,
description,
descriptionColorId,
- descriptionMaxLines);
+ descriptionMaxLines,
+ descriptionLinksClickable);
}
}
}
diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/simpleitems/SubtitmeListDividerItem.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/simpleitems/SubtitmeListDividerItem.java
new file mode 100644
index 0000000000..f429795bf1
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/simpleitems/SubtitmeListDividerItem.java
@@ -0,0 +1,31 @@
+package net.osmand.plus.base.bottomsheetmenu.simpleitems;
+
+import android.content.Context;
+import android.support.annotation.ColorRes;
+
+import net.osmand.plus.R;
+
+public class SubtitmeListDividerItem extends DividerItem {
+
+ public SubtitmeListDividerItem(Context context) {
+ super(context);
+ }
+
+ public SubtitmeListDividerItem(Context context, @ColorRes int colorId) {
+ super(context, colorId);
+ }
+
+ public SubtitmeListDividerItem(Context context, @ColorRes int colorId, int position) {
+ super(context, colorId, position);
+ }
+
+ @Override
+ protected int getBottomMargin(Context context) {
+ return 0;
+ }
+
+ @Override
+ protected int getLeftMargin(Context context) {
+ return context.getResources().getDimensionPixelSize(R.dimen.list_content_padding);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashErrorFragment.java b/OsmAnd/src/net/osmand/plus/dashboard/DashErrorFragment.java
index 478c26b466..136e50deab 100644
--- a/OsmAnd/src/net/osmand/plus/dashboard/DashErrorFragment.java
+++ b/OsmAnd/src/net/osmand/plus/dashboard/DashErrorFragment.java
@@ -1,10 +1,6 @@
package net.osmand.plus.dashboard;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
import android.graphics.Typeface;
-import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.view.ViewCompat;
@@ -15,19 +11,15 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
-import net.osmand.AndroidUtils;
-import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
-import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.OsmandActionBarActivity;
import net.osmand.plus.dashboard.tools.DashFragmentData;
-import net.osmand.plus.dialogs.ErrorBottomSheetDialog;
+import net.osmand.plus.dialogs.CrashBottomSheetDialogFragment;
import net.osmand.plus.helpers.FontCache;
-import java.io.File;
import java.text.MessageFormat;
public class DashErrorFragment extends DashBaseFragment {
@@ -38,7 +30,7 @@ public class DashErrorFragment extends DashBaseFragment {
// If settings null. No changes in setting will be made.
@Override
public boolean shouldShow(OsmandSettings settings, MapActivity activity, String tag) {
- return ErrorBottomSheetDialog.shouldShow(settings, activity);
+ return CrashBottomSheetDialogFragment.shouldShow(settings, activity);
}
};
private DismissListener dismissCallback;
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/CrashBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/CrashBottomSheetDialogFragment.java
new file mode 100644
index 0000000000..ded8574cf3
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/dialogs/CrashBottomSheetDialogFragment.java
@@ -0,0 +1,68 @@
+package net.osmand.plus.dialogs;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.FragmentManager;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+
+import net.osmand.PlatformUtil;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.R;
+import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.base.MenuBottomSheetDialogFragment;
+import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.SubtitleDividerItem;
+
+import org.apache.commons.logging.Log;
+
+public class CrashBottomSheetDialogFragment extends MenuBottomSheetDialogFragment {
+ public static final String TAG = "CrashBottomSheetDialogFragment";
+ private static final Log LOG = PlatformUtil.getLog(CrashBottomSheetDialogFragment.class);
+
+ @Override
+ public void createMenuItems(Bundle savedInstanceState) {
+ Context context = getContext();
+ if (context == null) {
+ return;
+ }
+
+ final View titleView = View.inflate(new ContextThemeWrapper(context, themeRes), R.layout.crash_title, null);
+ final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder()
+ .setCustomView(titleView)
+ .create();
+ items.add(titleItem);
+ }
+
+ @Override
+ protected int getRightBottomButtonTextId() {
+ return R.string.shared_string_send;
+ }
+
+ @Override
+ protected void onRightBottomButtonClick() {
+ OsmandApplication app = getMyApplication();
+ if (app != null) {
+ app.sendCrashLog();
+ }
+ dismiss();
+ }
+
+ public static boolean shouldShow(OsmandSettings settings, MapActivity activity) {
+ return activity.getMyApplication().getAppInitializer()
+ .checkPreviousRunsForExceptions(activity, settings != null);
+ }
+
+ public static void showInstance(@NonNull FragmentManager fm) {
+ try {
+ if (fm.findFragmentByTag(CrashBottomSheetDialogFragment.TAG) == null) {
+ CrashBottomSheetDialogFragment fragment = new CrashBottomSheetDialogFragment();
+ fragment.show(fm, CrashBottomSheetDialogFragment.TAG);
+ }
+ } catch (RuntimeException e) {
+ LOG.error("showInstance", e);
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/DislikeOsmAndBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/DislikeOsmAndBottomSheetDialogFragment.java
new file mode 100644
index 0000000000..4e39a67038
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/dialogs/DislikeOsmAndBottomSheetDialogFragment.java
@@ -0,0 +1,85 @@
+package net.osmand.plus.dialogs;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.FragmentManager;
+import android.support.v7.view.ContextThemeWrapper;
+import android.view.View;
+
+import net.osmand.PlatformUtil;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.R;
+import net.osmand.plus.base.MenuBottomSheetDialogFragment;
+import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
+
+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);
+
+ @Override
+ public void createMenuItems(Bundle savedInstanceState) {
+ Context context = getContext();
+ if (context == null) {
+ return;
+ }
+
+ final View titleView = View.inflate(new ContextThemeWrapper(context, themeRes), R.layout.dislike_title, null);
+ final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder()
+ .setCustomView(titleView)
+ .create();
+ items.add(titleItem);
+ }
+
+ @Override
+ protected int getDismissButtonTextId() {
+ return R.string.shared_string_cancel;
+ }
+
+ @Override
+ protected void onDismissButtonClickAction() {
+ OsmandApplication app = getMyApplication();
+ if (app != null) {
+ app.getSettings().RATE_US_STATE.set(RateUsBottomSheetDialog.RateUsState.DISLIKED_WITHOUT_MESSAGE);
+ }
+ }
+
+ @Override
+ protected int getRightBottomButtonTextId() {
+ return R.string.shared_string_send;
+ }
+
+ @Override
+ protected void onRightBottomButtonClick() {
+ OsmandApplication app = getMyApplication();
+ if (app != null) {
+ OsmandSettings settings = app.getSettings();
+ String email = getString(R.string.support_email);
+ settings.RATE_US_STATE.set(RateUsBottomSheetDialog.RateUsState.DISLIKED_WITH_MESSAGE);
+ settings.NUMBER_OF_APPLICATION_STARTS.set(0);
+ settings.LAST_DISPLAY_TIME.set(System.currentTimeMillis());
+ Intent sendEmail = new Intent(Intent.ACTION_SENDTO);
+ sendEmail.setType("text/plain");
+ sendEmail.setData(Uri.parse("mailto:" + email));
+ sendEmail.putExtra(Intent.EXTRA_EMAIL, email);
+ startActivity(sendEmail);
+ dismiss();
+ }
+ }
+
+ public static void showInstance(@NonNull FragmentManager fm) {
+ try {
+ if (fm.findFragmentByTag(DislikeOsmAndBottomSheetDialogFragment.TAG) == null) {
+ DislikeOsmAndBottomSheetDialogFragment fragment = new DislikeOsmAndBottomSheetDialogFragment();
+ fragment.show(fm, DislikeOsmAndBottomSheetDialogFragment.TAG);
+ }
+ } catch (RuntimeException e) {
+ LOG.error("showInstance", e);
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ErrorBottomSheetDialog.java b/OsmAnd/src/net/osmand/plus/dialogs/ErrorBottomSheetDialog.java
deleted file mode 100644
index 4d812da350..0000000000
--- a/OsmAnd/src/net/osmand/plus/dialogs/ErrorBottomSheetDialog.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package net.osmand.plus.dialogs;
-
-import android.graphics.Typeface;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.FragmentActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import net.osmand.plus.OsmandApplication;
-import net.osmand.plus.OsmandSettings;
-import net.osmand.plus.R;
-import net.osmand.plus.activities.MapActivity;
-import net.osmand.plus.activities.OsmandActionBarActivity;
-import net.osmand.plus.base.BottomSheetDialogFragment;
-import net.osmand.plus.helpers.FontCache;
-
-import java.text.MessageFormat;
-
-public class ErrorBottomSheetDialog extends BottomSheetDialogFragment {
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- FragmentActivity activity = requireActivity();
- OsmandApplication app = (OsmandApplication) activity.getApplication();
- View view = activity.getLayoutInflater().inflate(R.layout.dash_error_fragment, container, false);
- String msg = MessageFormat.format(getString(R.string.previous_run_crashed), OsmandApplication.EXCEPTION_PATH);
- Typeface typeface = FontCache.getRobotoMedium(activity);
- ImageView iv = ((ImageView) view.findViewById(R.id.error_icon));
- iv.setImageDrawable(app.getUIUtilities().getThemedIcon(R.drawable.ic_crashlog));
- TextView message = ((TextView) view.findViewById(R.id.error_header));
- message.setTypeface(typeface);
- message.setText(msg);
- Button errorBtn = ((Button) view.findViewById(R.id.error_btn));
- errorBtn.setTypeface(typeface);
- errorBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- OsmandApplication app = getMyApplication();
- if (app != null) {
- app.sendCrashLog();
- }
- dismiss();
- }
- });
-
- Button cancelBtn = ((Button) view.findViewById(R.id.error_cancel));
- cancelBtn.setTypeface(typeface);
- cancelBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- OsmandActionBarActivity dashboardActivity = ((OsmandActionBarActivity) getActivity());
- if (dashboardActivity != null) {
- dismiss();
- }
- }
- });
- return view;
- }
-
- public static boolean shouldShow(OsmandSettings settings, MapActivity activity) {
- return activity.getMyApplication().getAppInitializer()
- .checkPreviousRunsForExceptions(activity, settings != null);
- }
-}
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialog.java b/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialog.java
index c5663d87df..bd70893c37 100644
--- a/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialog.java
+++ b/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialog.java
@@ -83,7 +83,7 @@ public class RateUsBottomSheetDialog extends BottomSheetDialogFragment {
}
}
// Initial state now
- modifiedTime.add(Calendar.HOUR, -72);
+ modifiedTime.add(Calendar.MONTH, -1);
bannerFreeRuns = 3;
return modifiedTime.after(lastDisplayTime) && numberOfApplicationRuns >= bannerFreeRuns;
}
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialogFragment.java
new file mode 100644
index 0000000000..51b46fc143
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/dialogs/RateUsBottomSheetDialogFragment.java
@@ -0,0 +1,87 @@
+package net.osmand.plus.dialogs;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.FragmentManager;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+
+import net.osmand.PlatformUtil;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.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.base.bottomsheetmenu.simpleitems.SubtitleDividerItem;
+
+import org.apache.commons.logging.Log;
+
+import java.util.Calendar;
+
+public class RateUsBottomSheetDialogFragment extends MenuBottomSheetDialogFragment {
+ public static final String TAG = "RateUsBottomSheetDialogFragment";
+ private static final Log LOG = PlatformUtil.getLog(SendAnalyticsBottomSheetDialogFragment.class);
+
+ @Override
+ public void createMenuItems(Bundle savedInstanceState) {
+ Context context = getContext();
+ if (context == null) {
+ return;
+ }
+
+ final View titleView = View.inflate(new ContextThemeWrapper(context, themeRes), R.layout.rate_us_title, null);
+ final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder()
+ .setCustomView(titleView)
+ .create();
+ items.add(titleItem);
+ }
+
+ @Override
+ protected int getDismissButtonTextId() {
+ return R.string.shared_string_no;
+ }
+
+ @Override
+ protected void onDismissButtonClickAction() {
+ FragmentManager fm = getFragmentManager();
+ if (fm != null) {
+ DislikeOsmAndBottomSheetDialogFragment.showInstance(fm);
+ }
+ }
+
+ @Override
+ protected int getRightBottomButtonTextId() {
+ return R.string.button_rate;
+ }
+
+ @Override
+ protected void onRightBottomButtonClick() {
+ OsmandApplication app = getMyApplication();
+ if (app != null) {
+ app.getSettings().RATE_US_STATE.set(RateUsBottomSheetDialog.RateUsState.LIKED);
+ Uri uri = Uri.parse(Version.getUrlWithUtmRef(app, app.getPackageName()));
+ Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
+ startActivity(goToMarket);
+ dismiss();
+ }
+ }
+
+ public static boolean shouldShow(OsmandApplication app) {
+ return RateUsBottomSheetDialog.shouldShow(app);
+ }
+
+ public static void showInstance(@NonNull FragmentManager fm) {
+ try {
+ if (fm.findFragmentByTag(RateUsBottomSheetDialogFragment.TAG) == null) {
+ RateUsBottomSheetDialogFragment fragment = new RateUsBottomSheetDialogFragment();
+ fragment.show(fm, RateUsBottomSheetDialogFragment.TAG);
+ }
+ } catch (RuntimeException e) {
+ LOG.error("showInstance", e);
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/dialogs/SendAnalyticsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/SendAnalyticsBottomSheetDialogFragment.java
new file mode 100644
index 0000000000..5de0ee13ca
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/dialogs/SendAnalyticsBottomSheetDialogFragment.java
@@ -0,0 +1,193 @@
+package net.osmand.plus.dialogs;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.content.ContextCompat;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.TextPaint;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.URLSpan;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+
+import net.osmand.PlatformUtil;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.OsmandSettings.OsmandPreference;
+import net.osmand.plus.R;
+import net.osmand.plus.base.MenuBottomSheetDialogFragment;
+import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
+import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.SubtitleDividerItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.SubtitmeListDividerItem;
+import net.osmand.plus.chooseplan.OsmLiveCancelledDialog;
+
+import org.apache.commons.logging.Log;
+
+public class SendAnalyticsBottomSheetDialogFragment extends MenuBottomSheetDialogFragment {
+
+ public static final String TAG = "SendAnalyticsBottomSheetDialogFragment";
+ private static final Log LOG = PlatformUtil.getLog(SendAnalyticsBottomSheetDialogFragment.class);
+
+ private boolean sendAnonymousMapDownloadsData;
+ private boolean sendAnonymousAppUsageData;
+
+ @Override
+ public void createMenuItems(Bundle savedInstanceState) {
+ OsmandApplication app = getMyApplication();
+ Context context = getContext();
+ if (context == null || app == null) {
+ return;
+ }
+
+ final View titleView = View.inflate(new ContextThemeWrapper(context, themeRes), R.layout.make_better_title, null);
+ final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder()
+ .setCustomView(titleView)
+ .create();
+ items.add(titleItem);
+
+ items.add(new SubtitleDividerItem(context));
+
+ sendAnonymousMapDownloadsData = app.getSettings().SEND_ANONYMOUS_MAP_DOWNLOADS_DATA.get();
+ sendAnonymousAppUsageData = app.getSettings().SEND_ANONYMOUS_APP_USAGE_DATA.get();
+ final BottomSheetItemWithCompoundButton[] downloadedMapsItem = new BottomSheetItemWithCompoundButton[1];
+ downloadedMapsItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
+ .setChecked(sendAnonymousMapDownloadsData)
+ .setTitle(getString(R.string.downloaded_maps))
+ .setLayoutId(R.layout.bottom_sheet_item_with_switch_no_icon)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ boolean checked = !downloadedMapsItem[0].isChecked();
+ downloadedMapsItem[0].setChecked(checked);
+ sendAnonymousMapDownloadsData = checked;
+ updateBottomButtons();
+ }
+ })
+ .setTag("downloaded_maps")
+ .create();
+ items.add(downloadedMapsItem[0]);
+
+ items.add(new LongDescriptionItem(getString(R.string.downloaded_maps_collect_descr)));
+
+ items.add(new SubtitmeListDividerItem(context));
+
+ final BottomSheetItemWithCompoundButton[] visitedScreensItem = new BottomSheetItemWithCompoundButton[1];
+ visitedScreensItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
+ .setChecked(sendAnonymousAppUsageData)
+ .setTitle(getString(R.string.visited_screens))
+ .setLayoutId(R.layout.bottom_sheet_item_with_switch_no_icon)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ boolean checked = !visitedScreensItem[0].isChecked();
+ visitedScreensItem[0].setChecked(checked);
+ sendAnonymousAppUsageData = checked;
+ updateBottomButtons();
+ }
+ })
+ .setTag("visited_screens")
+ .create();
+ items.add(visitedScreensItem[0]);
+
+ items.add(new LongDescriptionItem(getString(R.string.visited_screens_collect_descr)));
+
+ items.add(new DividerItem(context));
+
+ String privacyPolicyText = getString(R.string.shared_string_privacy_policy);
+ String text = getString(R.string.privacy_and_security_change_descr, privacyPolicyText);
+
+ SpannableString spannable = new SpannableString(text);
+ int start = text.indexOf(privacyPolicyText);
+ int end = start + privacyPolicyText.length();
+ spannable.setSpan(new URLSpan(OsmandApplication.OSMAND_PRIVACY_POLICY_URL) {
+ @Override
+ public void updateDrawState(@NonNull TextPaint ds) {
+ super.updateDrawState(ds);
+ ds.setUnderlineText(false);
+ }
+ }, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ int linkTextColor = ContextCompat.getColor(context, !nightMode ? R.color.ctx_menu_bottom_view_url_color_light : R.color.ctx_menu_bottom_view_url_color_dark);
+ spannable.setSpan(new ForegroundColorSpan(linkTextColor), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ LongDescriptionItem descriptionItem = new LongDescriptionItem(spannable);
+ descriptionItem.setDescriptionLinksClickable(true);
+ items.add(descriptionItem);
+ }
+
+ @Override
+ protected boolean isRightBottomButtonEnabled() {
+ return sendAnonymousMapDownloadsData || sendAnonymousAppUsageData;
+ }
+
+ @Override
+ protected int getDismissButtonTextId() {
+ return R.string.shared_string_no_thank_you;
+ }
+
+ @Override
+ protected int getRightBottomButtonTextId() {
+ return R.string.shared_string_allow;
+ }
+
+ @Override
+ protected void onDismissButtonClickAction() {
+ OsmandApplication app = requiredMyApplication();
+ OsmandSettings settings = app.getSettings();
+ settings.SEND_ANONYMOUS_MAP_DOWNLOADS_DATA.set(false);
+ settings.SEND_ANONYMOUS_APP_USAGE_DATA.set(false);
+ settings.SEND_ANONYMOUS_DATA_REQUEST_PROCESSED.set(true);
+ }
+
+ @Override
+ protected void onRightBottomButtonClick() {
+ OsmandApplication app = requiredMyApplication();
+ OsmandSettings settings = app.getSettings();
+ settings.SEND_ANONYMOUS_MAP_DOWNLOADS_DATA.set(sendAnonymousMapDownloadsData);
+ settings.SEND_ANONYMOUS_APP_USAGE_DATA.set(sendAnonymousAppUsageData);
+ settings.SEND_ANONYMOUS_DATA_REQUEST_PROCESSED.set(true);
+ dismiss();
+ }
+
+ public static boolean shouldShowDialog(@NonNull OsmandApplication app) {
+ OsmandSettings settings = app.getSettings();
+ int requestsCount = settings.SEND_ANONYMOUS_DATA_REQUESTS_COUNT.get();
+ long firstInstalledDays = app.getAppInitializer().getFirstInstalledDays();
+ boolean requestProcessed = settings.SEND_ANONYMOUS_DATA_REQUEST_PROCESSED.get();
+ if (!requestProcessed && firstInstalledDays >= 5 && firstInstalledDays <= 30 && requestsCount < 3) {
+ if (requestsCount == 0) {
+ return true;
+ } else {
+ int numberOfStarts = app.getAppInitializer().getNumberOfStarts();
+ int lastRequestNS = settings.SEND_ANONYMOUS_DATA_LAST_REQUEST_NS.get();
+ return numberOfStarts - lastRequestNS > 2;
+ }
+ }
+ return false;
+ }
+
+ public static void showInstance(@NonNull OsmandApplication app, @NonNull FragmentManager fm) {
+ try {
+ if (fm.findFragmentByTag(SendAnalyticsBottomSheetDialogFragment.TAG) == null) {
+ SendAnalyticsBottomSheetDialogFragment fragment = new SendAnalyticsBottomSheetDialogFragment();
+ fragment.show(fm, SendAnalyticsBottomSheetDialogFragment.TAG);
+
+ OsmandSettings settings = app.getSettings();
+ int numberOfStarts = app.getAppInitializer().getNumberOfStarts();
+ OsmandPreference lastRequestNS = settings.SEND_ANONYMOUS_DATA_LAST_REQUEST_NS;
+ if (numberOfStarts != lastRequestNS.get()) {
+ OsmandPreference counter = settings.SEND_ANONYMOUS_DATA_REQUESTS_COUNT;
+ counter.set(counter.get() + 1);
+ lastRequestNS.set(numberOfStarts);
+ }
+ }
+ } catch (RuntimeException e) {
+ LOG.error("showInstance", e);
+ }
+ }
+}