diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 24811649b9..28d88ae8b9 100755
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -225,6 +225,25 @@
android:configChanges="orientation|screenSize|keyboardHidden|density|screenLayout|uiMode|fontScale"
android:launchMode="singleInstance"
android:theme="@style/Theme.AppCompat" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Progress.dismissDialog(Authorize.this, Progress.PROGRESS_OAUTH);
+ private class OAuthWebViewClient extends OsmWebViewClient {
@Override
public boolean handleLoading(WebView view, Uri uri) {
@@ -87,40 +78,19 @@ public boolean handleLoading(WebView view, Uri uri) {
}
@Override
- public WebResourceResponse handleIntercept(WebView view, Uri uri) {
- final String path = uri.getPath();
- if (path != null && path.toLowerCase().contains(MATOMO)) {
- return new WebResourceResponse(MimeTypes.TEXTPLAIN, "utf-8", new ByteArrayInputStream("".getBytes()));
- }
- return super.handleIntercept(view, uri);
+ public void exit() {
+ Authorize.this.exit();
}
@Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- synchronized (progressLock) {
- if (!progressShown) {
- progressShown = true;
- Progress.showDialog(Authorize.this, Progress.PROGRESS_OAUTH);
- }
- }
- }
+ protected void showProgressDialog() {
+ Progress.showDialog(Authorize.this, Progress.PROGRESS_OAUTH);
- @Override
- public void onPageFinished(WebView view, String url) {
- synchronized (progressLock) {
- synchronized (webViewLock) {
- if (progressShown && webView != null) {
- webView.removeCallbacks(dismiss);
- webView.postDelayed(dismiss, 500);
- }
- }
- }
}
@Override
- public void receivedError(WebView view, int errorCode, String description, String failingUrl) {
- exit();
- ScreenMessage.toastTopError(view.getContext(), description);
+ protected void dismissProgressDialog() {
+ Progress.dismissDialog(Authorize.this, Progress.PROGRESS_OAUTH);
}
}
diff --git a/src/main/java/de/blau/android/Main.java b/src/main/java/de/blau/android/Main.java
index 8bc816df26..bf38967d5f 100644
--- a/src/main/java/de/blau/android/Main.java
+++ b/src/main/java/de/blau/android/Main.java
@@ -2528,6 +2528,9 @@ public boolean read(FragmentActivity currentActivity, Uri fileUri) {
case R.id.tag_menu_reset_address_prediction:
Address.resetLastAddresses(this);
return true;
+ case R.id.menu_tools_signup:
+ Signup.startForResult(this, null);
+ break;
case R.id.menu_tools_oauth_reset: // reset the current OAuth tokens
if (server.getOAuth()) {
try (AdvancedPrefDatabase prefdb = new AdvancedPrefDatabase(this)) {
diff --git a/src/main/java/de/blau/android/Signup.java b/src/main/java/de/blau/android/Signup.java
new file mode 100644
index 0000000000..b4bdd7f228
--- /dev/null
+++ b/src/main/java/de/blau/android/Signup.java
@@ -0,0 +1,122 @@
+package de.blau.android;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.webkit.WebView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+import de.blau.android.dialogs.Progress;
+import de.blau.android.prefs.Preferences;
+import de.blau.android.util.ActivityResultHandler;
+import de.blau.android.util.OsmWebViewClient;
+import de.blau.android.util.WebViewActivity;
+
+/**
+ * Create a new OSM account
+ *
+ * Depends on the path of the page with the sign up form
+ *
+ * https://master.apis.dev.openstreetmap.org/user/new
+ *
+ * the format of confirmation url received in the received e-mail (see the app manifest)
+ *
+ * https://master.apis.dev.openstreetmap.org/user/SimonDev1234/confirm?confirm_string=7x4FHpz7zvd1O8Z8hd70NIxVQDvIXpFH
+ *
+ * and the query parameter added when the "Start mapping" button in clicked
+ *
+ * @author Simon
+ *
+ */
+public class Signup extends WebViewActivity {
+
+ private static final String DEBUG_TAG = Signup.class.getSimpleName();
+
+ public static final int REQUEST_CODE = Signup.class.hashCode() & 0x0000FFFF;
+
+ private static final String EDIT_HELP_VALUE = "1";
+ private static final String EDIT_HELP_PARAM = "edit_help";
+ private static final String USER_NEW_PATH = "/user/new";
+
+ /**
+ * Start a Signup activity
+ *
+ * @param activity calling activity
+ * @param listener an ActivityResult.Listener to process the result or null
+ */
+ public static void startForResult(@NonNull FragmentActivity activity, @Nullable ActivityResultHandler.Listener listener) {
+ Log.d(DEBUG_TAG, "startForResult");
+ if (!hasWebView(activity)) {
+ return;
+ }
+ Log.d(DEBUG_TAG, "request code " + REQUEST_CODE);
+ if (listener != null) {
+ if (activity instanceof ActivityResultHandler) {
+ ((ActivityResultHandler) activity).setResultListener(REQUEST_CODE, listener);
+ } else {
+ throw new ClassCastException("activity must implement ActivityResultHandler");
+ }
+ }
+
+ Intent intent = new Intent(activity, Signup.class);
+ activity.startActivityForResult(intent, REQUEST_CODE);
+ }
+
+ private class SignupViewClient extends OsmWebViewClient {
+
+ @Override
+ public boolean handleLoading(WebView view, Uri uri) {
+ final String editHelp = uri.getQueryParameter(EDIT_HELP_PARAM);
+ if (editHelp != null && editHelp.equals(EDIT_HELP_VALUE)) {
+ exit();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void exit() {
+ Signup.this.exit();
+ }
+
+ @Override
+ protected void showProgressDialog() {
+ Progress.showDialog(Signup.this, Progress.PROGRESS_WEBSITE);
+ }
+
+ @Override
+ protected void dismissProgressDialog() {
+ Progress.dismissDialog(Signup.this, Progress.PROGRESS_WEBSITE);
+ }
+ }
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ final Preferences prefs = App.getPreferences(this);
+ if (prefs.lightThemeEnabled()) {
+ setTheme(R.style.Theme_customMain_Light);
+ }
+ super.onCreate(savedInstanceState);
+
+ String dataUrl = getIntent().getDataString();
+ String signupUrl = dataUrl == null ? prefs.getServer().getWebsiteBaseUrl() + USER_NEW_PATH : dataUrl;
+
+ Log.d(DEBUG_TAG, "signup for " + signupUrl);
+ synchronized (webViewLock) {
+ webView = new WebView(this);
+ setContentView(webView);
+ webView.getSettings().setJavaScriptEnabled(true);
+ webView.setWebViewClient(new SignupViewClient());
+ loadUrlOrRestore(savedInstanceState, signupUrl);
+ }
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ Log.d(DEBUG_TAG, "onNewIntent");
+ super.onNewIntent(intent);
+ loadUrlOrRestore(null, intent.getDataString());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/blau/android/dialogs/Progress.java b/src/main/java/de/blau/android/dialogs/Progress.java
index de93b05103..3a22f7d0e1 100644
--- a/src/main/java/de/blau/android/dialogs/Progress.java
+++ b/src/main/java/de/blau/android/dialogs/Progress.java
@@ -37,6 +37,7 @@ public class Progress extends ImmersiveDialogFragment {
public static final int PROGRESS_LOADING_PRESET = 14;
public static final int PROGRESS_IMPORTING_FILE = 15;
public static final int PROGRESS_DOWNLOAD_TASKS = 16;
+ public static final int PROGRESS_WEBSITE = 17;
private int dialogType;
@@ -116,6 +117,7 @@ public static void dismissAll(@NonNull FragmentActivity activity) {
dismissDialog(activity, PROGRESS_LOADING_PRESET);
dismissDialog(activity, PROGRESS_IMPORTING_FILE);
dismissDialog(activity, PROGRESS_DOWNLOAD_TASKS);
+ dismissDialog(activity, PROGRESS_WEBSITE);
}
/**
@@ -159,6 +161,8 @@ private static String getTag(int dialogType) {
return "dialog_progress_importing_file";
case PROGRESS_DOWNLOAD_TASKS:
return "dialog_progress_download_tasks";
+ case PROGRESS_WEBSITE:
+ return "dialog_progress_website";
default:
Log.w(DEBUG_TAG, "Unknown dialog type " + dialogType);
}
diff --git a/src/main/java/de/blau/android/dialogs/ProgressDialog.java b/src/main/java/de/blau/android/dialogs/ProgressDialog.java
index 325af2100e..1ef13fb199 100644
--- a/src/main/java/de/blau/android/dialogs/ProgressDialog.java
+++ b/src/main/java/de/blau/android/dialogs/ProgressDialog.java
@@ -99,6 +99,10 @@ public static AlertDialog get(@NonNull Context ctx, int dialogType) {
titleId = R.string.progress_title;
messageId = R.string.progress_download_tasks_message;
break;
+ case Progress.PROGRESS_WEBSITE:
+ titleId = R.string.progress_general_title;
+ messageId = R.string.progress_website;
+ break;
default:
return null;
}
diff --git a/src/main/java/de/blau/android/util/DownloadActivity.java b/src/main/java/de/blau/android/util/DownloadActivity.java
index 6456428e71..8a154e3c37 100644
--- a/src/main/java/de/blau/android/util/DownloadActivity.java
+++ b/src/main/java/de/blau/android/util/DownloadActivity.java
@@ -107,7 +107,7 @@ public boolean handleLoading(@NonNull WebView view, @NonNull Uri uri) {
@Override
protected WebResourceResponse handleIntercept(WebView view, Uri uri) {
if (FAVICON.equals(uri.getLastPathSegment())) {
- return new WebResourceResponse(MimeTypes.PNG, "utf-8", new ByteArrayInputStream("".getBytes()));
+ return emptyResponse();
}
return super.handleIntercept(view, uri);
}
diff --git a/src/main/java/de/blau/android/util/OsmWebViewClient.java b/src/main/java/de/blau/android/util/OsmWebViewClient.java
new file mode 100644
index 0000000000..50d3b86402
--- /dev/null
+++ b/src/main/java/de/blau/android/util/OsmWebViewClient.java
@@ -0,0 +1,94 @@
+package de.blau.android.util;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.util.Log;
+import android.webkit.WebResourceResponse;
+import android.webkit.WebView;
+import androidx.annotation.Nullable;
+
+/**
+ * WebViewClient for some OSM website specifics
+ *
+ * @author Simon
+ *
+ */
+public abstract class OsmWebViewClient extends UpdatedWebViewClient {
+
+ private static final String DEBUG_TAG = OsmWebViewClient.class.getSimpleName();
+
+ private static final String MATOMO = "matomo";
+
+ private Runnable dismiss = () -> dismissProgressDialog();
+
+ private Object progressLock = new Object();
+ private boolean progressShown = false;
+
+ /**
+ * Manipulate the response to a query
+ *
+ * @param view the WebView
+ * @param uri the request Uri
+ * @return a WebResourceResponse or null if normal processing should continue
+ */
+ @Nullable
+ protected WebResourceResponse handleIntercept(WebView view, Uri uri) { // NOSONAR
+ // remove known trackers
+ final String path = uri.getPath();
+ if (path != null && path.toLowerCase().contains(MATOMO)) {
+ return emptyResponse();
+ }
+ return null;
+ }
+
+ @Override
+ public void receivedError(WebView view, int errorCode, String description, String failingUrl) {
+ exit();
+ ScreenMessage.toastTopError(view.getContext(), description);
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ synchronized (progressLock) {
+ if (!progressShown) {
+ progressShown = true;
+ showProgressDialog();
+ }
+ }
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ synchronized (progressLock) {
+ if (view != null) { // shouldn't happen but historically has
+ Context context = view.getContext();
+ if (context instanceof WebViewActivity) {
+ synchronized (((WebViewActivity) context).webViewLock) {
+ if (progressShown) {
+ view.removeCallbacks(dismiss);
+ view.postDelayed(dismiss, 500);
+ }
+ }
+ return;
+ }
+ }
+ Log.e(DEBUG_TAG, "onPageFinish context not a WebViewActivity");
+ }
+ }
+
+ /**
+ * Exit the activity holding the WebView
+ */
+ protected abstract void exit();
+
+ /**
+ * Show the progress dialog
+ */
+ protected abstract void showProgressDialog();
+
+ /**
+ * Dismiss the progress dialog
+ */
+ protected abstract void dismissProgressDialog();
+}
diff --git a/src/main/java/de/blau/android/util/UpdatedWebViewClient.java b/src/main/java/de/blau/android/util/UpdatedWebViewClient.java
index a3eaae0e3d..cb5d8b828c 100644
--- a/src/main/java/de/blau/android/util/UpdatedWebViewClient.java
+++ b/src/main/java/de/blau/android/util/UpdatedWebViewClient.java
@@ -1,5 +1,7 @@
package de.blau.android.util;
+import java.io.ByteArrayInputStream;
+
import android.annotation.TargetApi;
import android.net.Uri;
import android.os.Build;
@@ -10,6 +12,7 @@
import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import de.blau.android.contract.MimeTypes;
/**
* Class to handle some of the deprecations in Androids WebViewClient
@@ -18,7 +21,7 @@
*
*/
public abstract class UpdatedWebViewClient extends WebViewClient {
-
+
@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) { // nOSONAR
@@ -66,6 +69,15 @@ protected WebResourceResponse handleIntercept(WebView view, Uri uri) { // NOSONA
return null;
}
+ /**
+ * Create and return an empty WebResourceResponse
+ *
+ * @return an empty response
+ */
+ protected WebResourceResponse emptyResponse() {
+ return new WebResourceResponse(MimeTypes.TEXTPLAIN, "utf-8", new ByteArrayInputStream("".getBytes()));
+ }
+
@SuppressWarnings("deprecation")
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { // NOSONAR
diff --git a/src/main/res/menu-v24/main_menu_nosubmenus.xml b/src/main/res/menu-v24/main_menu_nosubmenus.xml
index 6c78ea5c58..e8833e5b6c 100644
--- a/src/main/res/menu-v24/main_menu_nosubmenus.xml
+++ b/src/main/res/menu-v24/main_menu_nosubmenus.xml
@@ -188,6 +188,9 @@
android:id="@+id/tag_menu_reset_address_prediction"
app:showAsAction="never"
android:title="@string/tag_menu_reset_address_prediction" />
+
diff --git a/src/main/res/menu/main_menu.xml b/src/main/res/menu/main_menu.xml
index 58ab46367b..f789f12d81 100644
--- a/src/main/res/menu/main_menu.xml
+++ b/src/main/res/menu/main_menu.xml
@@ -197,6 +197,9 @@
android:id="@+id/tag_menu_reset_address_prediction"
app:showAsAction="never"
android:title="@string/tag_menu_reset_address_prediction" />
+
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 37782d953c..5f40d86bf1 100755
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -102,6 +102,7 @@
Querying OAM…
Pruning…
Migrating…
+ Loading website…
"%1$s" deleted
"%1$s" changed
@@ -1036,9 +1037,10 @@
%1$s [wms]
Apply stored offset to imagery
- Contrast
- Reset OAuth
- Authorise OAuth
+ Contrast…
+ Reset authorisation (OAuth 1/2)
+ Authorise app (OAuth 1/2)…
+ Create OSM account…
Tag filter
Preset filter
Include way nodes