diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index daddf43b..1712ba7e 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -43,8 +43,6 @@
android:configChanges="orientation|screenSize"/>
-
diff --git a/src/main/java/medic/android/PromptForPermissionsActivity.java b/src/main/java/medic/android/PromptForPermissionsActivity.java
deleted file mode 100644
index 16acc39b..00000000
--- a/src/main/java/medic/android/PromptForPermissionsActivity.java
+++ /dev/null
@@ -1,166 +0,0 @@
-package medic.android;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
-import android.text.Html;
-import android.view.View;
-import android.widget.TextView;
-
-import org.medicmobile.webapp.mobile.R;
-
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS;
-import static org.medicmobile.webapp.mobile.MedicLog.trace;
-
-/**
- * To support Android 6.0+ (marshmallow), we must request SMS permissions at
- * runtime as well as in {@code AndroidManifest.xml}.
- * @see https://developer.android.com/intl/ru/about/versions/marshmallow/android-6.0-changes.html#behavior-runtime-permissions
- *
- * TODO this class was copy/pasted from medic-gateway. It should be pulled into
- * a separate lib so that both projects can share the same source.
- */
-public abstract class PromptForPermissionsActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
- private static final String X_IS_DEMAND = "isDemand";
- private static final String X_PERMISSIONS_TYPE = "permissionsType";
-
- private boolean isDemand;
- private boolean deniedBefore;
- private int permissionsRequestType;
-
-//> API
- protected abstract boolean refuseToFunctionWithoutPermissions();
- protected abstract Object[][] getPermissionRequests();
- protected abstract Class extends Activity> getNextActivityClass();
-
- @Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- isDemand = getIntent().getBooleanExtra(X_IS_DEMAND, false);
-
- trace(this, "onCreate() :: isDemand=%s, permissionsRequestType=%s", isDemand, permissionsRequestType);
-
- setContentView(R.layout.prompt_for_permissions);
-
- int promptTextId;
- if(isDemand) {
- promptTextId = R.string.txtDemandPermissions;
- } else {
- permissionsRequestType = getIntent().getIntExtra(X_PERMISSIONS_TYPE, 0);
- promptTextId = (int) getPermissionRequests()[permissionsRequestType][0];
- makePermissionRequest();
- }
-
- String appName = getResources().getString(R.string.app_name);
- CharSequence text = Html.fromHtml(getResources().getString(promptTextId, appName));
- ((TextView) findViewById(R.id.txtPermissionsPrompt)).setText(text);
- }
-
-//> EVENT HANDLERS
- public void btnOk_onClick(View v) {
- if(isDemand) {
- // open app manager for this app
- Intent i = new Intent(ACTION_APPLICATION_DETAILS_SETTINGS,
- Uri.fromParts("package", getPackageName(), null));
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(i);
-
- finish();
- } else makePermissionRequest();
- }
-
- @SuppressWarnings("PMD.UseVarargs")
- public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
- boolean allGranted = true;
- for(int res : grantResults) allGranted &= res == PERMISSION_GRANTED;
-
- if(allGranted) {
- nextActivity(this, permissionsRequestType + 1);
- } else if(refuseToFunctionWithoutPermissions()) {
- // For some flavours, we don't want to give people the option to use the app without the
- // correct permissions. If the permission is not granted, re-request the same.
- if(canShowPromptFor(this, permissionsRequestType)) { // NOPMD
- // Don't do anything - the user can re-read the on-screen advice.
- } else {
- // The user has checked the "don't ask me again"/"never allow" box (TODO which one?), so we have to step things up.
- startActivity(demandPermissions(this));
- finish();
- }
- } else {
- if(!deniedBefore && canShowPromptFor(this, permissionsRequestType)) {
- // Allow user to read the advice on the screen
- deniedBefore = true;
- } else nextActivity(this, permissionsRequestType + 1);
- }
- }
-
- protected void startPermissionsRequestChain(Activity a) {
- nextActivity(a, 0);
- }
-
- private void nextActivity(Activity a, int firstPermissionToConsider) {
- trace(a, "nextActivity() :: %s", firstPermissionToConsider);
-
- Intent next = null;
-
- for(int p=firstPermissionToConsider; p PRIVATE HELPERS
- private void makePermissionRequest() {
- ActivityCompat.requestPermissions(this, getPermissions(permissionsRequestType), 0);
- }
-
- private Intent requestPermission(Activity a, int permissionsRequestType) {
- trace(a, "requestPermission() :: p=%s", permissionsRequestType);
- Intent i = new Intent(a, getClass());
- i.putExtra(X_PERMISSIONS_TYPE, permissionsRequestType);
- i.putExtra(X_IS_DEMAND, false);
- return i;
- }
-
- private Intent demandPermissions(Activity a) {
- trace(a, "demandPermission()");
- Intent i = new Intent(a, getClass());
- i.putExtra(X_IS_DEMAND, true);
- return i;
- }
-}
diff --git a/src/main/java/org/medicmobile/webapp/mobile/EmbeddedBrowserActivity.java b/src/main/java/org/medicmobile/webapp/mobile/EmbeddedBrowserActivity.java
index dcbd725c..7a1a73b7 100644
--- a/src/main/java/org/medicmobile/webapp/mobile/EmbeddedBrowserActivity.java
+++ b/src/main/java/org/medicmobile/webapp/mobile/EmbeddedBrowserActivity.java
@@ -1,16 +1,14 @@
package org.medicmobile.webapp.mobile;
-import android.Manifest.permission;
+import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
import android.app.ActivityManager;
import android.net.Uri;
import android.net.ConnectivityManager;
import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.KeyEvent;
import android.view.Menu;
@@ -19,6 +17,7 @@
import android.view.Window;
import android.webkit.ValueCallback;
import android.widget.Toast;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import java.io.ByteArrayInputStream;
import java.util.Collections;
@@ -32,7 +31,6 @@
import org.xwalk.core.XWalkWebResourceRequest;
import org.xwalk.core.XWalkWebResourceResponse;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static java.lang.Boolean.parseBoolean;
import static org.medicmobile.webapp.mobile.BuildConfig.DEBUG;
import static org.medicmobile.webapp.mobile.BuildConfig.DISABLE_APP_URL_VALIDATION;
@@ -51,8 +49,7 @@ public class EmbeddedBrowserActivity extends LockableActivity {
static final int GRAB_PHOTO = (0 << 3) | NON_SIMPRINTS_FLAGS;
static final int GRAB_MRDT_PHOTO = (1 << 3) | NON_SIMPRINTS_FLAGS;
- private static final long FIVE_MINS = 5 * 60 * 1000;
- private static final float ANY_DISTANCE = 0f;
+ private final static int ACCESS_FINE_LOCATION_PERMISSION_REQUEST = (int)Math.random();
private static final ValueCallback IGNORE_RESULT = new ValueCallback() {
public void onReceiveValue(String result) { /* ignore */ }
@@ -108,7 +105,6 @@ public void onReceiveValue(String result) {
configureUseragent();
- enableLocationUpdates();
setUpUiClient(container);
enableRemoteChromeDebugging();
enableJavascript(container);
@@ -326,6 +322,25 @@ public void onGeolocationPermissionsShowPrompt(
});
}
+ public boolean getLocationPermissions() {
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PERMISSION_GRANTED) {
+ return true;
+ }
+
+ String[] permissions = { Manifest.permission.ACCESS_FINE_LOCATION };
+ ActivityCompat.requestPermissions(this, permissions, ACCESS_FINE_LOCATION_PERMISSION_REQUEST);
+ return false;
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ if (requestCode != ACCESS_FINE_LOCATION_PERMISSION_REQUEST) {
+ return;
+ }
+ String javaScript = "angular.element(document.body).injector().get('AndroidApi').v1.locationPermissionRequestResolved();";
+ evaluateJavascript(String.format(javaScript));
+ }
+
@SuppressLint("SetJavaScriptEnabled")
private void enableJavascript(XWalkView container) {
container.getSettings().setJavaScriptEnabled(true);
@@ -333,8 +348,6 @@ private void enableJavascript(XWalkView container) {
MedicAndroidJavascript maj = new MedicAndroidJavascript(this);
maj.setAlert(new Alert(this));
- maj.setLocationManager((LocationManager) this.getSystemService(Context.LOCATION_SERVICE));
-
maj.setActivityManager((ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE));
maj.setConnectivityManager((ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE));
@@ -342,58 +355,6 @@ private void enableJavascript(XWalkView container) {
container.addJavascriptInterface(maj, "medicmobile_android");
}
- /**
- * Make the app poll the location providers periodically. This should mean that calls
- * to MedicAndroidJavascript.getLocation() are reasonably up-to-date, and an initial
- * location is likely to have been resolved by the time the user first fills a form and
- * getLocation() is called. However, longer-term we are likely to want a more explicit
- * async getLocation() implementation which is triggered only when needed.
- * @see https://github.com/medic/medic-projects/issues/2629
- * @deprecated @see https://github.com/medic/medic-webapp/issues/3781
- */
- @Deprecated
- private void enableLocationUpdates() {
- if(ContextCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION) != PERMISSION_GRANTED) {
- log("EmbeddedBrowserActivity.enableLocationUpdates() :: Cannot enable location updates: permission ACCESS_FINE_LOCATION not granted.");
- return;
- }
-
- LocationManager m = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
-
- if(m == null) {
- log("EmbeddedBrowserActivity.enableLocationUpdates() :: Cannot enable location updates: LOCATION_SERVICE could not be fetched.");
- return;
- }
-
- requestLocationUpdates(m, LocationManager.GPS_PROVIDER);
- requestLocationUpdates(m, LocationManager.NETWORK_PROVIDER);
- }
-
- private void requestLocationUpdates(LocationManager m, String locationProvider) {
- try {
- if(m.isProviderEnabled(locationProvider)) {
- // Method bodies are empty because we need the location updates to be running constantly so
- // that recent location can be requested when required from Javascript.
- m.requestLocationUpdates(locationProvider, FIVE_MINS, ANY_DISTANCE, new LocationListener() {
- @SuppressWarnings("PMD.UncommentedEmptyMethodBody")
- public void onLocationChanged(Location location) {}
- @SuppressWarnings("PMD.UncommentedEmptyMethodBody")
- public void onProviderDisabled(String provider) {}
- @SuppressWarnings("PMD.UncommentedEmptyMethodBody")
- public void onProviderEnabled(String provider) {}
- @SuppressWarnings("PMD.UncommentedEmptyMethodBody")
- public void onStatusChanged(String provider, int status, Bundle extras) {}
- });
- } else {
- log("EmbeddedBrowserActivity.requestLocationUpdates(%s) :: Cannot get updates: not enabled or phone does not have this feature.",
- locationProvider);
- }
- } catch(SecurityException ex) {
- log(ex, "EmbeddedBrowserActivity.requestLocationUpdates(%s) :: Exception thrown while checking provider.",
- locationProvider);
- }
- }
-
private void enableStorage(XWalkView container) {
XWalkSettings settings = container.getSettings();
diff --git a/src/main/java/org/medicmobile/webapp/mobile/MedicAndroidJavascript.java b/src/main/java/org/medicmobile/webapp/mobile/MedicAndroidJavascript.java
index 3b7d5abd..3dc6e1f3 100644
--- a/src/main/java/org/medicmobile/webapp/mobile/MedicAndroidJavascript.java
+++ b/src/main/java/org/medicmobile/webapp/mobile/MedicAndroidJavascript.java
@@ -1,12 +1,8 @@
package org.medicmobile.webapp.mobile;
-import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.DatePickerDialog;
-import android.location.Criteria;
-import android.location.Location;
-import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
@@ -47,7 +43,6 @@ public class MedicAndroidJavascript {
private final MrdtSupport mrdt;
private final SmsSender smsSender;
- private LocationManager locationManager;
private ActivityManager activityManager;
private ConnectivityManager connectivityManager;
private Alert soundAlert;
@@ -63,10 +58,6 @@ public void setAlert(Alert soundAlert) {
this.soundAlert = soundAlert;
}
- public void setLocationManager(LocationManager locationManager) {
- this.locationManager = locationManager;
- }
-
public void setActivityManager(ActivityManager activityManager) {
this.activityManager = activityManager;
}
@@ -122,32 +113,10 @@ private JSONObject getDataUsage(long rx, long tx) throws JSONException {
.put("tx", tx);
}
- @Deprecated
@org.xwalk.core.JavascriptInterface
@android.webkit.JavascriptInterface
- @SuppressLint("MissingPermission") // handled by catch(Exception)
- /**
- * @deprecated Location should be fetched directly from the browser.
- * @see https://github.com/medic/medic-webapp/issues/3781
- */
- public String getLocation() {
- try {
- if(locationManager == null) return jsonError("LocationManager not set. Cannot retrieve location.");
-
- String provider = locationManager.getBestProvider(new Criteria(), true);
- if(provider == null) return jsonError("No location provider available.");
-
- Location loc = locationManager.getLastKnownLocation(provider);
-
- if(loc == null) return jsonError("Provider '" + provider + "' did not provide a location.");
-
- return new JSONObject()
- .put("lat", loc.getLatitude())
- .put("long", loc.getLongitude())
- .toString();
- } catch(Exception ex) {
- return jsonError("Problem fetching location: ", ex);
- }
+ public boolean getLocationPermissions() {
+ return this.parent.getLocationPermissions();
}
@org.xwalk.core.JavascriptInterface
diff --git a/src/main/java/org/medicmobile/webapp/mobile/MmPromptForPermissionsActivity.java b/src/main/java/org/medicmobile/webapp/mobile/MmPromptForPermissionsActivity.java
deleted file mode 100644
index 5dcd1ed7..00000000
--- a/src/main/java/org/medicmobile/webapp/mobile/MmPromptForPermissionsActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.medicmobile.webapp.mobile;
-
-import android.Manifest.permission;
-import android.app.Activity;
-
-import medic.android.PromptForPermissionsActivity;
-
-public class MmPromptForPermissionsActivity extends PromptForPermissionsActivity {
- private static final Object[][] PERMISSIONS_REQUESTS = {
- /* location */ { R.string.txtPermissionsPrompt_location, new String[] { permission.ACCESS_COARSE_LOCATION, permission.ACCESS_FINE_LOCATION } },
- };
-
- @Override protected boolean refuseToFunctionWithoutPermissions() { return true; }
-
- @Override protected Object[][] getPermissionRequests() { return PERMISSIONS_REQUESTS; }
-
- @Override protected Class extends Activity> getNextActivityClass() { return EmbeddedBrowserActivity.class; }
-
- public static void startPermissionsRequestChainFrom(Activity from) {
- new MmPromptForPermissionsActivity().startPermissionsRequestChain(from);
- }
-}
diff --git a/src/main/java/org/medicmobile/webapp/mobile/SettingsDialogActivity.java b/src/main/java/org/medicmobile/webapp/mobile/SettingsDialogActivity.java
index ac72f419..affd41f2 100644
--- a/src/main/java/org/medicmobile/webapp/mobile/SettingsDialogActivity.java
+++ b/src/main/java/org/medicmobile/webapp/mobile/SettingsDialogActivity.java
@@ -139,7 +139,7 @@ private void backToWebview() {
private void saveSettings(WebappSettings s) {
try {
settings.updateWith(s);
- MmPromptForPermissionsActivity.startPermissionsRequestChainFrom(this);
+ this.backToWebview();
} catch(IllegalSettingsException ex) {
if(DEBUG) trace(ex, "Tried to save illegal setting.");
for(IllegalSetting error : ex.errors) {
diff --git a/src/main/java/org/medicmobile/webapp/mobile/Utils.java b/src/main/java/org/medicmobile/webapp/mobile/Utils.java
index 7447e7e6..7b62451f 100644
--- a/src/main/java/org/medicmobile/webapp/mobile/Utils.java
+++ b/src/main/java/org/medicmobile/webapp/mobile/Utils.java
@@ -37,11 +37,11 @@ static boolean intentHandlerAvailableFor(Context ctx, Intent intent) {
static void startAppActivityChain(Activity a) {
if(SettingsStore.in(a).hasWebappSettings()) {
- MmPromptForPermissionsActivity.startPermissionsRequestChainFrom(a);
+ a.startActivity(new Intent(a, EmbeddedBrowserActivity.class));
} else {
a.startActivity(new Intent(a, SettingsDialogActivity.class));
- a.finish();
}
+ a.finish();
}
public static ProgressDialog showSpinner(Context ctx, int messageId) {
diff --git a/src/main/res/layout/prompt_for_permissions.xml b/src/main/res/layout/prompt_for_permissions.xml
deleted file mode 100644
index 2da179cf..00000000
--- a/src/main/res/layout/prompt_for_permissions.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index f2d99fef..5d77ad39 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -45,19 +45,4 @@
Choose image
Compressing imageā¦
-
-
- Warning: %1$s does not currently have permission to check current location.
-
This permission is required so that %1$s can correctly log report locations.
- ]]>
-
-
-
- Warning: %1$s does not currently have all required permissions.
-
%1$s will not work without the required permissions.
-
Please enable all permissions.
- ]]>
-