Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: get user ID without requiring scary (for user) permissions?

In order to manage user preferences, at present I'm grabbing the google user name (effectively the email address they've registered to the device) and using (a hash of) that as a "user ID" to distinguish between different users. Something along the lines of what is described here.

That all works fine, but some users are (understandably) scared off by any permission that seems to give the app some evil power to trawl through their account info or contacts.

EDIT: this issue is even more acute with the way in which Google has now implemented Permission Groups in the Android 6 runtime permission schema. They have put GET_ACCOUNTS into the CONTACTS permission group. So now, in order to generate a unique anonymous User ID, the user has to be presented with a dialog that says:

Allow this app to access your contacts? | Deny | Allow |

How misleading is that?? My app has no wish to access contacts, but the user is being asked to grant permission for the app to access contacts! Yes, there is an opportunity to explain to the user with a separate dialog that, in fact, access to contacts is NOT required, but then they still get the stock system dialog that asks them to grant permission to access contacts... naturally they will think "why am I being asked to grant this permission if access to contacts is not required?" and "do I really trust the developer? they say access to contacts is not required, but is that really true?"... very very confusing and a very poor user experience IMHO (and the opinion of others too).

I'd rather just avoid all of this hassle and confusion and obtain a unique user ID without special permissions being required.

So is there a stock function or method in the SDK that will return a unique user ID for the user, without requiring any additional permission? I'm kinda surprised if there isn't, because it would seem to be quite a common thing to want to do... to have a user ID for managing app users.

Two points:

(a) I only need an anonymous user ID... I don't actually need the user's email address, nor would I ever want the user's email address. So I can't see why google can't provide a getUserID() method that returns a unique anonymised ID, without having to grant special permissions to the app.

(b) It has to be a user ID, not a device ID, so that it will work across all of the user's devices registered to the same google account.

Thanks.

like image 908
drmrbrewer Avatar asked Oct 09 '15 08:10

drmrbrewer


People also ask

Is there a unique Android device ID?

Secure#ANDROID_ID returns the Android ID as an unique for each user 64-bit hex string. It's known to be null sometimes, it's documented as "can change upon factory reset". Use at your own risk, and it can be easily changed on a rooted phone.

How do I find users on Android?

as you have linked with online database and you want to assign identity to each user,you have to go with any of 4 options and for sake of simplicity option 1: register/login will be better.in registration task you can include very minimum details like just username and password .

What is runtime permission in Android?

Runtime permissions prevent apps from gaining access to private data without a user's consent, and provide them with additional context and visibility into the types of permissions that applications are either seeking, or have been granted.

What is signature permission in Android?

" signature " A permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user's explicit approval.


2 Answers

If you use Google Play Services you can get the account type and account name without any extra permissions.

First, add the following dependency to build.gradle:

compile 'com.google.android.gms:play-services-auth:8.4.0'

Next, launch the account chooser intent:

Intent intent = AccountPicker.newChooseAccountIntent(null, null,
    new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE},
    false, null, null, null, null);

try {
  startActivityForResult(intent, REQUEST_CODE_EMAIL);
} catch (ActivityNotFoundException e) {
  // This device may not have Google Play Services installed.
  // TODO: do something else
}

Finally, override onActivityResult to get the account type and account name:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == REQUEST_CODE_EMAIL && resultCode == RESULT_OK) {
    String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
    String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
    // TODO: do something with the accountName
    return;
  }
  super.onActivityResult(requestCode, resultCode, data);
}

source: https://stackoverflow.com/a/19444640/1048340

like image 101
Jared Rummler Avatar answered Oct 28 '22 00:10

Jared Rummler


You can get the exact gmail email address using AccountPicker without requiring to add the permissions.

Your app needs to include the Google Play Services but it doesn't need any permissions.

This whole process will fail on older versions of Android (2.2+ is required), or if Google Play is not available so you should consider that case.

Sample code from the source:

private static final int REQUEST_CODE_EMAIL = 1;
    private TextView email = (TextView) findViewById(R.id.email);

    // ...

    try {
        Intent intent = AccountPicker.newChooseAccountIntent(null, null,
                new String[] { GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE }, false, null, null, null, null);
        startActivityForResult(intent, REQUEST_CODE_EMAIL);
    } catch (ActivityNotFoundException e) {
        // TODO
    }

    // ...

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE_EMAIL && resultCode == RESULT_OK) {
            String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
            email.setText(accountName);
        }
    }

Source of the above information is : This Answer on SO - to a similar but slightly different question asked in the past.

This Post - also has some nice approaches that would serve your purpose.

like image 36
AndroidMechanic - Viral Patel Avatar answered Oct 28 '22 02:10

AndroidMechanic - Viral Patel