How to add programmatically a custom account in android?

后端 未结 3 1441
执笔经年
执笔经年 2020-11-27 12:11

I am trying to create an account for my app, where I will be able to have my contacts against my account like facebook, viber, whatsapp etc. I want my account to be visible

3条回答
  •  野性不改
    2020-11-27 12:48

    I have written a library for this, which gets you free from doing the chores needed for managing android accounts, such as defining a bound service, authenticator xml, etc. Working with that is in 5 simple steps:

    Step 1

    Add this to dependencies for build.gradle of the app:

    compile 'com.digigene.android:account-authenticator:1.3.0'
    

    Step 2

    Define your authentication account type as a string in strings.xml:

    DigiGene
    

    Replace ‘DigiGene’ with your own account type. This is what appears in Android Accounts in this screenshot.

    Step 3

    Design your registration layout for registering the users (e.g. this image):

    
    
    
        
    
        
    
        

    and make a new class, say MyRegistrationActivity.java, with the following code:

    import com.digigene.accountauthenticator.activity.RegistrationActivity;
    
    public class MyRegistrationActivity extends RegistrationActivity {
        private EditText accountNameEditText, passwordEditText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.registration_layout);
            accountNameEditText = (EditText) findViewById(R.id.account_name);
            passwordEditText = (EditText) findViewById(R.id.password);
        }
    
        public void startAuthentication(View view) {
            register(accountNameEditText.getText().toString(), passwordEditText.getText().toString(),
                    null, null);
        }
    }
    

    Step 4

    Make an entry layout as in here:

    
    
    
        
    
        

    This layout goes with the following class:

    import com.digigene.accountauthenticator.AuthenticatorManager;
    
    public class MainActivity extends Activity {
        EditText accountNameEditText;
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            accountNameEditText = (EditText) findViewById(R.id.account_name);
        }
    
        public void signIn(View view) {
            AuthenticatorManager authenticatorManager = new AuthenticatorManager(MainActivity.this,
                    getString(R.string.auth_account_type), this, MyRegistrationActivity.class,
                    MyInterfaceImplementation.class);
            String authTokenType = "REGULAR_USER";
            AuthenticatorManager.authenticatorManager = authenticatorManager;
            authenticatorManager.getAccessToken(accountNameEditText.getText().toString(),
                    authTokenType, null);
        }
    
        public void addUser(View view) {
            AuthenticatorManager authenticatorManager = new AuthenticatorManager(MainActivity.this,
                    getString(R.string.auth_account_type), this, MyRegistrationActivity.class,
                    MyInterfaceImplementation.class);
            String authTokenType = "REGULAR_USER";
            AuthenticatorManager.authenticatorManager = authenticatorManager;
            authenticatorManager.addAccount(authTokenType, null, null);
        }
    }
    

    Step 5

    This is the last step in which the methods needed to connect to the server for registration and sign-in purposes and after that are implemented. In the following, contrary to a real case, server connections are mocked, just to demonstrate the functionality of the library. You may replace the following implementation with your own real one.

    import com.digigene.accountauthenticator.AbstractInterfaceImplementation;
    import com.digigene.accountauthenticator.AuthenticatorManager;
    import com.digigene.accountauthenticator.result.RegisterResult;
    import com.digigene.accountauthenticator.result.SignInResult;
    import com.digigene.accountauthenticator.result.SignUpResult;
    
    public class MyInterfaceImplementation extends AbstractInterfaceImplementation {
        public static int accessTokenCounter = 0;
        public static int refreshTokenCounter = 0;
        public static int demoCounter = 0;
        public static int accessTokenNo = 0;
        public static int refreshTokenNo = 0;
        public final int ACCESS_TOKEN_EXPIRATION_COUNTER = 2;
        public final int REFRESH_TOKEN_EXPIRATION_COUNTER = 5;
        public final int DEMO_COUNTER = 15;
    
        @Override
        public String[] userAccessTypes() {
            return new String[]{"REGULAR_USER", "SUPER_USER"};
        }
    
        @Override
        public void doAfterSignUpIsUnsuccessful(Context context, Account account, String
                authTokenType, SignUpResult signUpResult, Bundle options) {
            Toast.makeText(context, "Sign-up was not possible due to the following:\n" + signUpResult
                    .errMessage, Toast.LENGTH_LONG).show();
            AuthenticatorManager.authenticatorManager.addAccount(authTokenType, null, options);
        }
    
        @Override
        public void doAfterSignInIsSuccessful(Context context, Account account, String authTokenType,
                                              String authToken, SignInResult signInResult, Bundle
                                                      options) {
            demoCounter = demoCounter + 1;
            Toast.makeText(context, "User is successfully signed in: \naccessTokenNo=" +
                    accessTokenNo + "\nrefreshTokenNo=" + refreshTokenNo +
                    "\ndemoCounter=" + demoCounter, Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public SignInResult signInToServer(Context context, Account account, String authTokenType,
                                           String accessToken, Bundle options) {
            accessTokenCounter = accessTokenCounter + 1;
            SignInResult signInResult = new SignInResult();
            signInResult.isSuccessful = true;
            synchronized (this) {
                try {
                    this.wait(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if ((accessTokenCounter > ACCESS_TOKEN_EXPIRATION_COUNTER || demoCounter > DEMO_COUNTER)) {
                signInResult.isSuccessful = false;
                signInResult.isAccessTokenExpired = true;
                if (demoCounter < DEMO_COUNTER) {
                    signInResult.errMessage = "Access token is expired";
                    return signInResult;
                }
            }
            return signInResult;
        }
    
        @Override
        public SignUpResult signUpToServer(Context context, Account account, String authTokenType,
                                           String refreshToken, Bundle options) {
            SignUpResult signUpResult = new SignUpResult();
            synchronized (this) {
                try {
                    this.wait(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            refreshTokenCounter = refreshTokenCounter + 1;
            signUpResult.isSuccessful = true;
            signUpResult.accessToken = "ACCESS_TOKEN_NO_" + accessTokenNo;
            signUpResult.refreshToken = "REFRESH_TOKEN_NO_" + refreshTokenNo;
            if (demoCounter > DEMO_COUNTER) {
                signUpResult.isSuccessful = false;
                signUpResult.errMessage = "You have reached your limit of using the demo version. " +
                        "Please buy it for further usage";
                return signUpResult;
            }
            if (refreshTokenCounter > REFRESH_TOKEN_EXPIRATION_COUNTER) {
                refreshTokenCounter = 0;
                signUpResult.isSuccessful = false;
                signUpResult.errMessage = "User credentials have expired, please login again";
                return signUpResult;
            }
            if (accessTokenCounter > ACCESS_TOKEN_EXPIRATION_COUNTER) {
                accessTokenCounter = 0;
                accessTokenNo = accessTokenNo + 1;
                signUpResult.accessToken = "ACCESS_TOKEN_NO_" + accessTokenNo;
            }
            return signUpResult;
        }
    
        @Override
        public RegisterResult registerInServer(Context context, Account account, String password,
                                               String authTokenType, String[] requiredFeatures,
                                               Bundle options) {
            RegisterResult registerResult = new RegisterResult();
            registerResult.isSuccessful = false;
            synchronized (this) {
                try {
                    this.wait(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (true) {  // password is checked here and, if true, refresh token is generated for the
                // user
                refreshTokenNo = refreshTokenNo + 1;
                accessTokenNo = accessTokenNo + 1;
                registerResult.isSuccessful = true;
                registerResult.refreshToken = "REFRESH_TOKEN_NO_" + refreshTokenNo;
            }
            return registerResult;
        }
    
        @Override
        public boolean setDoesCallbackRunInBackgroundThread() {
            return false;
        }
    }
    

    Results

    The following shows the library in action. You can find the complete tutorial here and about how AccountManager in android works in these three posts from my website:part 1, part 2, part 3.

提交回复
热议问题