1. 程式人生 > >Android AccountManager帳號管理(二)

Android AccountManager帳號管理(二)

Android AccountManager 帳號管理(一)分享瞭如何將自己的帳號體系註冊到系統服務AccountManagerService,統一由AccountManager來管理,這僅是自己的一點理解;但開發者對接的工作遠不止如此,還有使用者登入完成後如何將帳號新增到系統資料庫中等等,AccountManager都有提供相對應的介面

在說介面之前,先看一下AccountManager會用到的兩個介面類

一個是android.accounts.AccountManagerFuture

AccountManagerFuture類似於java的Future,提供了對AccountManager任務的執行進行取消,查詢是否已經被取消,是否完成以及獲取執行結果,通過getResult方法獲取執行結果,該方法會阻塞直到任務返回結果

public interface AccountManager<V> {
/**取消任務的執行
如果任務已經完成/已經取消/不能被取消,則返回false
*/
boolean cancel(boolean mayInterruptIfRunning);
/**任務是否被取消
如果任務在完成之前被取消,則返回true
*/
boolean isCancelled();
/**任務是否完成
*/
boolean isDone();
/**獲取任務的執行結果
這個介面可能會阻塞當前執行緒,直到任務完成/任務被cancel,故不要在主線呼叫此介面
*/
V getResult() throws OperationCanceledException, IOException, AuthenticatorException;
/**同上
引數規定了等待的時間timeout,如果超時,則會直接被cancel
*/
V getResult(long timeout, TimeUnit unit) throws OperationCanceledException, IOException, AuthenticatorException; }

另一個是android.accounts.AccountManagerCallback

AccountManagerCallback,即AccountManager介面的回撥,可在主執行緒執行

public interface AccountManagerCallback<V> {
   void run(AccountManagerFuture<V> future);
}

接下來分享一點自己對AccountManager提供的介面的理解,介面協議是由IAccountManager定義的

1. 獲取AccountManager例項:

/**
獲取AccountManager例項
備註:context最好傳遞application context,避免可能的不必要的記憶體洩漏
*/
public static AccountManager get(Context context);

2. 針對於註冊帳號的authenticator app,需瞭解以下介面

下面這些即將列出的方法主要是for authenticator app,其他需要app主要是呼叫authToken相關方法
所以下面下列方法的呼叫是有許可權求的:呼叫下面介面的app,要與對應帳號的authenticator app簽名一致
還有一點:下面方法均可在主執行緒呼叫

/**
將一個帳號直接儲存到AccountManager
*/
public boolean addAccountExplicitly(Account account, String password, Bundle userdata) 
/**
獲取account的password(不一定是真實的使用者密碼,看authenticator app的儲存)
*/
public String getPassword(final Account account);
/**
重置該account的password
注意:呼叫這個方法會清除該賬號所有authToken在AccountManager中的快取
*/
public void setPassword(final Account account, final String password) ;
/**
清除account的password
注意: 呼叫這個方法會清除該賬號的password及authToken在AccountManager中的快取
*/
public void clearPassword(final Account account) ;
/**
將account對應key-value儲存在AccountManager中
*/
public void setUserData(final Account account, final String key, final String value);
/**
獲取和該帳號相關的對應key值的value
*/
public String getUserData(final Account account, final String key);
/**
從AccountManager中刪除account,由authenticator app決定是否可以刪除該帳號
注意:這個方法可以在主執行緒呼叫,但是返回的AccountManagerFuture不能在主執行緒中使用
*/
public AccountManagerFuture<Bundle> removeAccount(final Account account, final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler);
/**
直接從AccountManager資料庫中刪除account
*/
public boolean removeAccountExplicitly(Account account);

3. 下面介面供需要使用帳號服務的apps呼叫,當然authenticator app也可呼叫

/**
獲取和該帳號相關的對應key值的value
備註:這個方法可在主執行緒呼叫
許可權要求:和註冊account的authenticator app簽名一致
*/
public String getUserData(final Account account, final String key);
/**
獲取當前註冊到AccountManager中的所有authenticator app的屬性(即在authenticator xml中定義的account屬性,再加上authenticator app的包名)
備註:這個方法可在主執行緒呼叫
*/
public AuthenticatorDescription[] getAuthenticatorTypes();
/**
獲取當前儲存到AccountManager的所有帳號列表,和getAccountsByType(null)相同
備註:這個方法可在主執行緒呼叫
許可權要求:需要GET_ACCOUNTS的許可權(這個許可權在android 6.0及以上是執行時許可權,需要動態申請)
*/
public Account[] getAccounts() ;

public Account[] getAccountsByTypeForPackage(String type, String packageName) ;
/**
獲取特定account type
備註:這個方法可在主執行緒呼叫
許可權要求:需要GET_ACCOUNTS的許可權(這個許可權在android 6.0及以上是執行時許可權,需要動態申請)
*/
public Account[] getAccountsByType(String type);

/**
刪除儲存AccountManager中此賬號型別對應的authToken快取,應用必須呼叫這個方法將快取的authToken置為過期,否則getAuthToken獲取到的一直是快取的token
備註:這個方法可以在主執行緒中呼叫
*/
public void invalidateAuthToken(final String accountType, final String authToken) ;
/**
獲取AccountManager快取的某個賬號對應authTokenType的authToken
如果快取中沒有對應authTokenType的token值,並不會重新生成,而是直接返回false
備註:這個方法可以在主執行緒中呼叫
許可權要求:和註冊account的authenticator app簽名相同
*/
public String peekAuthToken(final Account account, final String authTokenType) ;
/**
將一個account對應autheTokenType的authToken快取在AccountManager中
備註:這個方法可以在主執行緒中呼叫
許可權要求:和註冊account的authenticator app簽名相同
*/
public void setAuthToken(Account account, final String authTokenType, final String authToken);
/**
同步獲取account對應authTokenType的authToken
notifyAuthFailure,如果authenticator app返回出錯,要不要彈通知提醒
備註:這個方法可以可能涉及到網路請求,不要在主執行緒呼叫
許可權要求:和註冊account的authenticator app簽名相同
*/
public String blockingGetAuthToken(Account account, String authTokenType, boolean notifyAuthFailure);
/**
許可權要求:和註冊account的authenticator app簽名相同
*/
public AccountManagerFuture<Bundle> getAuthToken(final Account account, final String authTokenType, final Bundle options, final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler);
/**
許可權要求:和註冊account的authenticator app簽名相同
*/
public AccountManagerFuture<Bundle> getAuthToken(final Account account, final String authTokenType, final Bundle options, final boolean notifyAuthFailure, AccountManagerCallback<Bundle> callback, Handler handler);
/**
要求使用者新增某個特定accountType的帳號,如沒有則會引導註冊(authenticator app自己的處理)
注意:呼叫這個介面會調起authenticator app帳號登入的頁面。傳的activity引數就是用來啟動這個intent的:如果傳的activity引數不為null,則AccountManager會自動幫你start 登入的intent,否則你自己呼叫future.getResult(),返回的結果中會有AccountManager#KEY_INTENT對應的帳號登入頁面的intent
*/
public AccountManagerFuture<Bundle> addAccount(final String accountType, final String authTokenType, final String[] requiredFeatures, final Bundle addAccountOptions, final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler);
/**
認證使用者的身份(一般是驗證帳號的密碼)
注意:驗證的行為由authenticator app來定義,同addAccount會調起authenticator app認證的頁面
*/
public AccountManagerFuture<Bundle> confirmCredentials(final Account account, final Bundle options, final Activity activity, final AccountManagerCallback<Bundle> callback, final Handler handler);

4. 除了以上介面外,還有一些獲取帳號屬性等介面

/**
獲取當前註冊到AccountManager中的所有authenticator app的屬性(即在authenticator xml中定義的account屬性,再加上authenticator app的包名)
備註:這個方法可在主執行緒呼叫
*/
public AuthenticatorDescription[] getAuthenticatorTypes();