Skip to content

Commit

Permalink
Location disclosure refactor: change dialog by an activity / layout
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsarm committed Dec 22, 2020
1 parent 62b8e29 commit 4ee7d20
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 74 deletions.
2 changes: 2 additions & 0 deletions src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
android:screenOrientation="portrait"/>
<activity android:name="SettingsDialogActivity"
android:screenOrientation="portrait"/>
<activity android:name="RequestPermissionActivity"
android:screenOrientation="portrait"/>
<activity android:name="AppUrlIntentActivity" android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.medicmobile.webapp.mobile;

import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.TextView;

import static org.medicmobile.webapp.mobile.MedicLog.trace;

/**
* Shows a confirmation view that displays a "prominent" disclosure about how
* the user geolocation data is used, asking to confirm whether to allow the app to
* access the location or not.
*
* If the user accepts, a request to the API to access the location is made by the main activity,
* but Android will show another confirmation dialog. If the user decline the first
* confirmation, the request to the API is omitted and the decision recorded to avoid
* requesting the same next time.
*/
public class RequestPermissionActivity extends LockableActivity {

@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.request_permission);
String message = getResources().getString(R.string.locRequest_message);
String appName = getResources().getString(R.string.app_name);
TextView field = (TextView) findViewById(R.id.locMessageText);
field.setText(String.format(message, appName));
}

public void onClickOk(View view) {
trace(this, "onClickOk() :: user accepted to share the location");
setResult(RESULT_OK);
finish();
}

public void onClickNegative(View view) {
trace(this, ":: onClickNegative() :: user denied to share the location");
setResult(RESULT_CANCELED);
finish();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,8 @@ String get(String key) {

/**
* Returns true if the user has denied to provide its geolocation data.
* The rejection is taken from the first dialog with the "prominent" disclosure
* The rejection is taken from the first view with the "prominent" disclosure
* about the location data, not from the native dialog displayed by Android.
*
* @see RequestPermissionDialog
*/
boolean hasUserDeniedGeolocation() {
return prefs.getBoolean("denied-geolocation", false);
Expand Down
11 changes: 11 additions & 0 deletions src/main/res/drawable-anydpi/location_pin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#63A2C6"
android:alpha="0.8">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
</vector>
Binary file added src/main/res/drawable-hdpi/location_pin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/res/drawable-mdpi/location_pin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/res/drawable-xhdpi/location_pin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/res/drawable-xxhdpi/location_pin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 79 additions & 0 deletions src/main/res/layout/request_permission.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">

<ImageView
android:id="@+id/locIcon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="128dp"
android:contentDescription="@string/locRequest_IconDescription"
android:scaleType="center"
android:scaleX="2"
android:scaleY="2"
android:src="@drawable/location_pin" />

<TextView
android:id="@+id/locTitleText"
style="@android:style/Widget.DeviceDefault.Light.TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/locIcon"
android:layout_marginTop="10dp"
android:gravity="center"
android:padding="10dp"
android:text="@string/locRequest_title"
android:textSize="18sp"
android:textStyle="bold" />

<TextView
android:id="@+id/locMessageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/locTitleText"
android:layout_marginTop="10dp"
android:gravity="center"
android:padding="20dp"
android:text="@string/locRequest_message"
android:textSize="18sp" />

<LinearLayout
android:id="@+id/locButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingBottom="20dp">

<Button
android:id="@+id/locNegativeButton"
style="@style/Widget.AppCompat.Button.Borderless.Blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickNegative"
android:text="@string/locRequest_denyButton"
tools:ignore="OnClick" />

<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />

<Button
android:id="@+id/locOkButton"
style="@style/Widget.AppCompat.Button.Borderless.Blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickOk"
android:text="@string/locRequest_okButton"
tools:ignore="OnClick" />
</LinearLayout>

</RelativeLayout>
4 changes: 3 additions & 1 deletion src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@

<string name="locRequest_title">Location Access</string>
<string name="locRequest_message">%s collects location data when you submit a form to analyze and improve health outcomes in your area. Select \"Allow while using the app\" on the next screen to turn on your location access.</string>
<string name="locRequest_okButton">OK</string>
<string name="locRequest_okButton">Turn on</string>
<string name="locRequest_denyButton">No thanks</string>
<string name="locRequest_IconDescription">My location icon</string>
<string name="locRequest_mapIconDescription">Location in map icon</string>
</resources>
4 changes: 4 additions & 0 deletions src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@
<item name="android:paddingLeft">32dp</item>
<item name="android:paddingRight">32dp</item>
</style>
<style name="Widget.AppCompat.Button.Borderless.Blue" parent="Widget.AppCompat.Button.Borderless">
<item name="android:textColor">#0073cd</item>
<item name="android:textAllCaps">false</item>
</style>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
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.Menu;
import android.view.MenuItem;
Expand Down Expand Up @@ -43,8 +44,11 @@ public class EmbeddedBrowserActivity extends LockableActivity {
private static final int NON_SIMPRINTS_FLAGS = 0x7;
static final int GRAB_PHOTO = (0 << 3) | NON_SIMPRINTS_FLAGS;
static final int GRAB_MRDT_PHOTO = (1 << 3) | NON_SIMPRINTS_FLAGS;
private static final int ACCESS_FINE_LOCATION_PERMISSION_REQUEST = (int)(Math.random() * 1000);

private final static int ACCESS_FINE_LOCATION_PERMISSION_REQUEST = (int)(Math.random() * 1000);
private static final int DISCLOSURE_LOCATION_PERMISSION_REQUEST = 1122331;

private static final String[] LOCATION_PERMISSIONS = { Manifest.permission.ACCESS_FINE_LOCATION };

private static final ValueCallback<String> IGNORE_RESULT = new ValueCallback<String>() {
public void onReceiveValue(String result) { /* ignore */ }
Expand Down Expand Up @@ -179,6 +183,25 @@ protected void onStart() {
default:
trace(this, "onActivityResult() :: no handling for requestCode=%s", requestCode);
}
} else if(requestCode == DISCLOSURE_LOCATION_PERMISSION_REQUEST) {
// User accepted or denied to allow the app to access
// location data in RequestPermissionActivity
if (resultCode == RESULT_OK) { // user accepted
// Request to Android location data access
ActivityCompat.requestPermissions(
this,
LOCATION_PERMISSIONS,
ACCESS_FINE_LOCATION_PERMISSION_REQUEST);
} else if (resultCode == RESULT_CANCELED) { // user rejected
try {
this.locationRequestResolved();
settings.setUserDeniedGeolocation();
} catch (SettingsException e) {
error(e, "Error recording negative to access location");
} catch (Exception e) {
error(e, "Unknown Error recording negative to access location");
}
}
} else {
String js = simprints.process(requestCode, i);
trace(this, "Execing JS: %s", js);
Expand Down Expand Up @@ -308,7 +331,14 @@ public boolean getLocationPermissions() {
trace(this, "getLocationPermissions() :: already granted");
return true;
}
RequestPermissionDialog.show(this, ACCESS_FINE_LOCATION_PERMISSION_REQUEST);
if (settings.hasUserDeniedGeolocation()) {
trace(this, "getLocationPermissions() :: user has previously denied to share location");
return false;
}
trace(this, "getLocationPermissions() :: location never granted, requesting access...");
startActivityForResult(
new Intent(this, RequestPermissionActivity.class),
DISCLOSURE_LOCATION_PERMISSION_REQUEST);
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
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;
Expand Down Expand Up @@ -50,6 +51,10 @@ public class EmbeddedBrowserActivity extends LockableActivity {

private final static int ACCESS_FINE_LOCATION_PERMISSION_REQUEST = (int)Math.random();

private static final int DISCLOSURE_LOCATION_PERMISSION_REQUEST = 1122331;

private static final String[] LOCATION_PERMISSIONS = { Manifest.permission.ACCESS_FINE_LOCATION };

private static final ValueCallback<String> IGNORE_RESULT = new ValueCallback<String>() {
public void onReceiveValue(String result) { /* ignore */ }
};
Expand Down Expand Up @@ -185,6 +190,25 @@ public void onReceiveValue(String result) {
default:
trace(this, "onActivityResult() :: no handling for requestCode=%s", requestCode);
}
} else if(requestCode == DISCLOSURE_LOCATION_PERMISSION_REQUEST) {
// User accepted or denied to allow the app to access
// location data in RequestPermissionActivity
if (resultCode == RESULT_OK) { // user accepted
// Request to Android location data access
ActivityCompat.requestPermissions(
this,
LOCATION_PERMISSIONS,
ACCESS_FINE_LOCATION_PERMISSION_REQUEST);
} else if (resultCode == RESULT_CANCELED) { // user rejected
try {
this.locationRequestResolved();
settings.setUserDeniedGeolocation();
} catch (SettingsException e) {
error(e, "Error recording negative to access location");
} catch (Exception e) {
error(e, "Unknown Error recording negative to access location");
}
}
} else {
String js = simprints.process(requestCode, i);
trace(this, "Execing JS: %s", js);
Expand Down Expand Up @@ -326,7 +350,14 @@ public boolean getLocationPermissions() {
trace(this, "getLocationPermissions() :: already granted");
return true;
}
RequestPermissionDialog.show(this, ACCESS_FINE_LOCATION_PERMISSION_REQUEST);
if (settings.hasUserDeniedGeolocation()) {
trace(this, "getLocationPermissions() :: user has previously denied to share location");
return false;
}
trace(this, "getLocationPermissions() :: location never granted, requesting access...");
startActivityForResult(
new Intent(this, RequestPermissionActivity.class),
DISCLOSURE_LOCATION_PERMISSION_REQUEST);
return false;
}

Expand Down

0 comments on commit 4ee7d20

Please sign in to comment.