Skip to content

Commit

Permalink
Merge pull request getodk#2474 from grzesiek2010/GET_ACCOUNTS_AND_SEN…
Browse files Browse the repository at this point in the history
…D_SMS

GET_ACCOUNTS and SEND_SMS permissions
  • Loading branch information
lognaturel authored Aug 17, 2018
2 parents 6ac6651 + 9797cc0 commit 804542b
Show file tree
Hide file tree
Showing 29 changed files with 159 additions and 135 deletions.
1 change: 0 additions & 1 deletion collect_app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ dependencies {
implementation "com.karumi:dexter:4.2.0"
implementation "org.osmdroid:osmdroid-android:5.6.4"
implementation "org.slf4j:slf4j-android:1.6.1-RC1"
implementation "pub.devrel:easypermissions:0.2.1"
implementation("com.google.api-client:google-api-client-android:1.22.0") {
exclude group: 'org.apache.httpcomponents'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public void onCreate(Bundle savedInstanceState) {
*/
private void getResultsFromApi() {
if (!accountsManager.isGoogleAccountSelected()) {
accountsManager.chooseAccount();
accountsManager.chooseAccountAndRequestPermissionIfNeeded();
} else {
if (isDeviceOnline()) {
toDownload.clear();
Expand All @@ -236,13 +236,6 @@ private void getResultsFromApi() {
}
}

@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
accountsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

/**
* Checks whether the device currently has a network connection.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;

import org.odk.collect.android.R;
import org.odk.collect.android.application.Collect;
Expand Down Expand Up @@ -153,21 +152,14 @@ private void runTask() {
*/
private void getResultsFromApi() {
if (!accountsManager.isGoogleAccountSelected()) {
accountsManager.chooseAccount();
accountsManager.chooseAccountAndRequestPermissionIfNeeded();
} else if (!isDeviceOnline()) {
ToastUtils.showShortToast("No network connection available.");
} else {
runTask();
}
}

@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
accountsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

/**
* Called when an activity launched here (specifically, AccountPicker
* and authorization) exits, giving you the requestCode you started it with,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import static org.odk.collect.android.preferences.PreferenceKeys.KEY_SUBMISSION_TRANSPORT_TYPE;
import static org.odk.collect.android.tasks.sms.SmsSender.SMS_INSTANCE_ID;
import static org.odk.collect.android.utilities.PermissionUtils.finishAllActivities;
import static org.odk.collect.android.utilities.PermissionUtils.requestSendSMSPermission;
import static org.odk.collect.android.utilities.PermissionUtils.requestStoragePermissions;

/**
Expand Down Expand Up @@ -292,7 +293,16 @@ private void uploadSelectedFiles(int buttonId) {
Transport transport = Transport.fromPreference(GeneralSharedPreferences.getInstance().get(KEY_SUBMISSION_TRANSPORT_TYPE));

if (transport.equals(Transport.Sms) || buttonId == R.id.sms_upload_button) {
smsService.submitForms(instanceIds);
requestSendSMSPermission(this, new PermissionListener() {
@Override
public void granted() {
smsService.submitForms(instanceIds);
}

@Override
public void denied() {
}
});
} else {

String server = (String) GeneralSharedPreferences.getInstance().get(KEY_PROTOCOL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v7.content.res.AppCompatResources;
import android.telephony.PhoneNumberUtils;
import android.text.InputFilter;
Expand Down Expand Up @@ -231,21 +230,14 @@ public void initAccountPreferences() {
selectedGoogleAccountPreference.setSummary(accountsManager.getSelectedAccount());
selectedGoogleAccountPreference.setOnPreferenceClickListener(preference -> {
if (PlayServicesUtil.isGooglePlayServicesAvailable(getActivity())) {
accountsManager.chooseAccount();
accountsManager.chooseAccountAndRequestPermissionIfNeeded();
} else {
PlayServicesUtil.showGooglePlayServicesAvailabilityErrorDialog(getActivity());
}
return true;
});
}

@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
accountsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

private void addUrlToPreferencesList(String url, SharedPreferences prefs) {
urlList.add(0, url);
String urlListString = new Gson().toJson(urlList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.odk.collect.android.tasks.InstanceServerUploader;
import org.odk.collect.android.tasks.ServerPollingJob;
import org.odk.collect.android.utilities.IconUtils;
import org.odk.collect.android.utilities.PermissionUtils;
import org.odk.collect.android.utilities.WebUtils;
import org.odk.collect.android.utilities.gdrive.GoogleAccountsManager;

Expand All @@ -46,6 +47,8 @@ public class NetworkReceiver extends BroadcastReceiver implements InstanceUpload

InstanceGoogleSheetsUploader instanceGoogleSheetsUploader;

private String resultMessage;

@Override
public void onReceive(Context context, Intent intent) {
// make sure sd card is ready, if not don't try to send
Expand Down Expand Up @@ -131,17 +134,22 @@ private void uploadForms(Context context, boolean isFormAutoSendOptionEnabled) {
String protocol = (String) settings.get(PreferenceKeys.KEY_PROTOCOL);

if (protocol.equals(context.getString(R.string.protocol_google_sheets))) {
String googleUsername = (String) settings.get(PreferenceKeys.KEY_SELECTED_GOOGLE_ACCOUNT);
if (googleUsername == null || googleUsername.isEmpty()) {
// just quit if there's no username
running = false;
return;
if (PermissionUtils.checkIfGetAccountsPermissionGranted(context)) {
String googleUsername = (String) settings.get(PreferenceKeys.KEY_SELECTED_GOOGLE_ACCOUNT);
if (googleUsername == null || googleUsername.isEmpty()) {
// just quit if there's no username
running = false;
return;
}
GoogleAccountsManager accountsManager = new GoogleAccountsManager(Collect.getInstance());
accountsManager.getCredential().setSelectedAccountName(googleUsername);
instanceGoogleSheetsUploader = new InstanceGoogleSheetsUploader(accountsManager);
instanceGoogleSheetsUploader.setUploaderListener(this);
instanceGoogleSheetsUploader.execute(toSendArray);
} else {
resultMessage = Collect.getInstance().getString(R.string.odk_permissions_fail);
uploadingComplete(null);
}
GoogleAccountsManager accountsManager = new GoogleAccountsManager(Collect.getInstance());
accountsManager.getCredential().setSelectedAccountName(googleUsername);
instanceGoogleSheetsUploader = new InstanceGoogleSheetsUploader(accountsManager);
instanceGoogleSheetsUploader.setUploaderListener(this);
instanceGoogleSheetsUploader.execute(toSendArray);
} else if (protocol.equals(context.getString(R.string.protocol_odk_default))) {
// get the username, password, and server from preferences

Expand Down Expand Up @@ -194,7 +202,9 @@ public void uploadingComplete(HashMap<String, String> result) {
String message;

if (result == null) {
message = Collect.getInstance().getString(R.string.odk_auth_auth_fail);
message = resultMessage != null
? resultMessage
: Collect.getInstance().getString(R.string.odk_auth_auth_fail);
} else {
StringBuilder selection = new StringBuilder();
Set<String> keys = result.keySet();
Expand Down Expand Up @@ -236,7 +246,7 @@ public void uploadingComplete(HashMap<String, String> result) {
}

private String getContentText(Map<String, String> result) {
return allFormsDownloadedSuccessfully(result)
return result != null && allFormsDownloadedSuccessfully(result)
? Collect.getInstance().getString(R.string.success)
: Collect.getInstance().getString(R.string.failures);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,79 @@ public void onPermissionRationaleShouldBeShown(PermissionRequest permission, Per
.check();
}

public static void requestGetAccountsPermission(@NonNull Activity activity, @NonNull PermissionListener action) {
com.karumi.dexter.listener.single.PermissionListener permissionListener = new com.karumi.dexter.listener.single.PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
action.granted();
}

@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Light_Dialog);

builder.setTitle(R.string.get_accounts_runtime_permission_denied_title)
.setMessage(R.string.get_accounts_runtime_permission_denied_desc)
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> action.denied())
.setCancelable(false)
.setIcon(R.drawable.ic_get_accounts)
.show();
}

@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
};

Dexter.withActivity(activity)
.withPermission(
Manifest.permission.GET_ACCOUNTS
).withListener(permissionListener)
.withErrorListener(error -> Timber.i(error.name()))
.check();
}

public static void requestSendSMSPermission(@NonNull Activity activity, @NonNull PermissionListener action) {
com.karumi.dexter.listener.single.PermissionListener permissionListener = new com.karumi.dexter.listener.single.PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
action.granted();
}

@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Light_Dialog);

builder.setTitle(R.string.send_sms_runtime_permission_denied_title)
.setMessage(R.string.send_sms_runtime_permission_denied_desc)
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> action.denied())
.setCancelable(false)
.setIcon(R.drawable.ic_sms)
.show();
}

@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
};

Dexter.withActivity(activity)
.withPermission(
Manifest.permission.SEND_SMS
).withListener(permissionListener)
.withErrorListener(error -> Timber.i(error.name()))
.check();
}

public static boolean checkIfStoragePermissionsGranted(Context context) {
int read = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE);
int write = ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);

return read == PackageManager.PERMISSION_GRANTED && write == PackageManager.PERMISSION_GRANTED;
}

public static boolean checkIfCameraPermissionGranted(Context context) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}
Expand All @@ -209,6 +275,10 @@ public static boolean checkIfLocationPermissionsGranted(Context context) {
&& accessCoarseLocation == PackageManager.PERMISSION_GRANTED;
}

public static boolean checkIfGetAccountsPermissionGranted(Context context) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.GET_ACCOUNTS) == PackageManager.PERMISSION_GRANTED;
}

/**
* Checks to see if an activity is one of the entry points to the app i.e
* an activity that has a view action that can launch the app.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

package org.odk.collect.android.utilities.gdrive;

import android.Manifest;
import android.accounts.Account;
import android.app.Activity;
import android.app.Fragment;
Expand All @@ -35,23 +34,20 @@
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.drive.DriveScopes;

import org.odk.collect.android.R;
import org.odk.collect.android.listeners.PermissionListener;
import org.odk.collect.android.preferences.GeneralSharedPreferences;
import org.odk.collect.android.preferences.PreferenceKeys;
import org.odk.collect.android.utilities.ThemeUtils;
import org.odk.collect.android.utilities.ToastUtils;

import java.util.Collections;
import java.util.List;

import pub.devrel.easypermissions.EasyPermissions;
import timber.log.Timber;

public class GoogleAccountsManager implements EasyPermissions.PermissionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
import static org.odk.collect.android.utilities.PermissionUtils.requestGetAccountsPermission;

public class GoogleAccountsManager implements GoogleApiClient.OnConnectionFailedListener {

public static final int REQUEST_ACCOUNT_PICKER = 1000;
private static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1002;
private static final int RESOLVE_CONNECTION_REQUEST_CODE = 5555;

@Nullable
Expand Down Expand Up @@ -81,7 +77,8 @@ public GoogleAccountsManager(@NonNull Activity activity) {

public GoogleAccountsManager(@NonNull Fragment fragment) {
this.fragment = fragment;
initCredential(fragment.getActivity());
activity = fragment.getActivity();
initCredential(activity);
}

public GoogleAccountsManager(@NonNull Context context) {
Expand Down Expand Up @@ -123,50 +120,30 @@ public void setSelectedAccountName(String accountName) {
}
}

@Override
public void onPermissionsGranted(int requestCode, List<String> list) {
if (listener != null) {
listener.onGoogleAccountSelected(credential.getSelectedAccountName());
}
}

@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
ToastUtils.showShortToast("Permission denied");
}

public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
EasyPermissions.onRequestPermissionsResult(
requestCode, permissions, grantResults, this);
}
public void chooseAccountAndRequestPermissionIfNeeded() {
if (activity != null) {
requestGetAccountsPermission(activity, new PermissionListener() {
@Override
public void granted() {
chooseAccount();
}

public void chooseAccount() {
if (checkAccountPermission()) {
String accountName = getSelectedAccount();
if (autoChooseAccount && !accountName.isEmpty()) {
selectAccount(accountName);
} else {
showAccountPickerDialog();
}
@Override
public void denied() {
}
});
} else {
requestAccountPermission();
chooseAccount();
}
}

public void requestAccountPermission() {
EasyPermissions.requestPermissions(
context,
context.getString(R.string.request_permissions_google_account),
REQUEST_PERMISSION_GET_ACCOUNTS, Manifest.permission.GET_ACCOUNTS);
}

/**
* Returns true if has accounts permission otherwise false
*/
public boolean checkAccountPermission() {
return EasyPermissions.hasPermissions(context, Manifest.permission.GET_ACCOUNTS);
private void chooseAccount() {
String accountName = getSelectedAccount();
if (autoChooseAccount && !accountName.isEmpty()) {
selectAccount(accountName);
} else {
showAccountPickerDialog();
}
}

public String getSelectedAccount() {
Expand Down
Loading

0 comments on commit 804542b

Please sign in to comment.