很多代码......我从Android的官方示例代码SampleSyncAdapter中得到了这个
无论如何,这里是代码。我没有包括同步类,我只是想让该帐户显示并能够暂时创建。
帐户验证器类:
package com.tagapp.android;
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.accounts.NetworkErrorException;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class AccountAuthenticator extends AbstractAccountAuthenticator {
private Context mContext;
public AccountAuthenticator(Context context) {
super(context);
mContext = context;
}
@Override
public Bundle addAccount(AccountAuthenticatorResponse response,
String accountType, String authTokenType,
String[] requiredFeatures, Bundle options) {
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
Account account, Bundle options) throws NetworkErrorException {
if(options != null && options.containsKey(AccountManager.KEY_PASSWORD)) {
String password = options.getString(AccountManager.KEY_PASSWORD);
boolean verified = onlineConfirmPassword(account.name, password);
Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, verified);
return result;
}
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
intent.putExtra(AuthenticatorActivity.PARAM_CONFIRM_CREDENTIALS, true);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
private boolean onlineConfirmPassword(String username, String password) {
return RestClient.authenticate(username, password, null, null);
}
@Override
public Bundle editProperties(AccountAuthenticatorResponse response,
String accountType) {
throw new UnsupportedOperationException();
}
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options) {
if(!authTokenType.equals("com.tagapp.android")) {
Bundle result = new Bundle();
result.putString(AccountManager.KEY_ERROR_MESSAGE, "invalid authtokenType");
return result;
}
AccountManager am = AccountManager.get(mContext);
String password = am.getPassword(account);
if(password != null) {
boolean verified = onlineConfirmPassword(account.name, password);
if(verified) {
Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, "com.tagapp.android");
result.putString(AccountManager.KEY_AUTHTOKEN, password);
return result;
}
}
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public String getAuthTokenLabel(String authTokenType) {
if("com.tagapp.android".equals(authTokenType)) {
return "Tag";
}
return null;
}
@Override
public Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features) throws NetworkErrorException {
Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
return result;
}
@Override
public Bundle updateCredentials(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options) {
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
intent.putExtra(AuthenticatorActivity.PARAM_CONFIRM_CREDENTIALS, false);
Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
}
AccountAuthenticationActivity 类:
package com.tagapp.android;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.TextView;
公共类 AuthenticatorActivity 扩展 AccountAuthenticatorActivity {
public static final String PARAM_AUTHTOKEN_TYPE = "authtokenType";
public static final String PARAM_USERNAME = "username";
public static final String PARAM_CONFIRM_CREDENTIALS = "confirmCredentials";
public static final String PARAM_PASSWORD = "password";
private AccountManager mAccountManager;
private Thread mAuthThread;
private String mAuthtoken;
private String mAuthtokenType;
private Boolean mConfirmCredentials = false;
private final Handler mHandler = new Handler();
private TextView mMessageView;
private String mPassword;
private String mUsername;
private EditText mPasswordEdit;
private EditText mUsernameEdit;
private boolean mRequestNewAccount = false;
@Override
public void onCreate(Bundle neato) {
super.onCreate(neato);
mAccountManager = AccountManager.get(this);
Intent intent = getIntent();
mUsername = intent.getStringExtra(PARAM_USERNAME);
mAuthtokenType = intent.getStringExtra(PARAM_AUTHTOKEN_TYPE);
mConfirmCredentials = intent.getBooleanExtra(PARAM_CONFIRM_CREDENTIALS, false);
initLayout();
}
private void initLayout() {
setContentView(R.layout.account_sync_login);
requestWindowFeature(Window.FEATURE_LEFT_ICON);
mMessageView = (TextView)findViewById(R.id.account_login_message);
mUsernameEdit = (EditText)findViewById(R.id.account_login_username_edittext);
mPasswordEdit = (EditText)findViewById(R.id.account_login_password_edittext);
mUsernameEdit.setText(mUsername);
if(getMessage() != null) {
mMessageView.setText(getMessage());
}
}
private CharSequence getMessage() {
if(TextUtils.isEmpty(mUsername)) {
CharSequence msg = "Enter your username and password.";
return msg;
}
if(TextUtils.isEmpty(mPassword)) {
return "Enter your password.";
}
return null;
}
@Override
protected Dialog onCreateDialog(int id) {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Authenticating...");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
if(mAuthThread != null) {
mAuthThread.interrupt();
finish();
}
}
});
return dialog;
}
public void handleLogin(View v) {
if(mRequestNewAccount) {
mUsername = mUsernameEdit.getText().toString();
}
mPassword = mPasswordEdit.getText().toString();
if(TextUtils.isEmpty(mUsername) || TextUtils.isEmpty(mPassword)) {
mMessageView.setText(getMessage());
}
else {
showProgress();
mAuthThread = RestClient.attemptAuth(mUsername, mPassword, mHandler, this);
}
}
private void finishConfirmCredentials(boolean result) {
Account account = new Account(mUsername, "com.tagapp.android");
mAccountManager.setPassword(account, mPassword);
Intent intent = new Intent();
intent.putExtra(AccountManager.KEY_BOOLEAN_RESULT, result);
setAccountAuthenticatorResult(intent.getExtras());
setResult(RESULT_OK, intent);
finish();
}
private void finishLogin() {
Account account = new Account(mUsername, "com.taggapp.android");
if(mRequestNewAccount) {
mAccountManager.addAccountExplicitly(account, mPassword, null);
ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true);
}
else {
mAccountManager.setPassword(account, mPassword);
}
Intent intent = new Intent();
mAuthtoken = mPassword;
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mUsername);
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, "com.tagapp.android");
if(mAuthtokenType != null && mAuthtokenType.equals("com.tagapp.android")) {
intent.putExtra(AccountManager.KEY_AUTHTOKEN, mAuthtoken);
}
setAccountAuthenticatorResult(intent.getExtras());
setResult(RESULT_OK, intent);
finish();
}
private void showProgress() {
showDialog(0);
}
private void hideProgress() {
dismissDialog(0);
}
public void onAuthenticationResult(boolean result) {
hideProgress();
if(result) {
if(!mConfirmCredentials) {
finishLogin();
}
else {
finishConfirmCredentials(true);
}
}
else {
if(mRequestNewAccount) {
mMessageView.setText("You got it all wrong.");
}
else {
mMessageView.setText("Wrong password.");
}
}
}
}
AuthenticatorService 类:
package com.tagapp.android;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class AccountAuthenticatorService extends Service {
private AccountAuthenticator mAuthenticator;
@Override
public void onCreate() {
mAuthenticator = new AccountAuthenticator(this);
}
@Override
public IBinder onBind(Intent intent) {
return mAuthenticator.getIBinder();
}
}
清单包括以下内容:
<service android:name=".authenticator.AccountAuthenticatorService"
android:exported="true">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator"/>
</service>
和...
<activity android:name=".AuthenticatorActivity"
android:label="Sync Tag Account!"
android:theme="@android:style/Theme.Dialog"
android:excludeFromRecents="true">
服务中引用的 xml 文件在这里:
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.tagapp.android"
android:icon="@drawable/taglogo"
android:smallIcon="@drawable/launchicon"
android:label="Tag"/>
我知道这是很多代码......但我已经非常绝望地试图为此找到结果。据我了解,这应该可以正常工作,但是当我添加帐户时,它会超时/崩溃,或者只是不显示我的应用程序帐户作为添加选项。我已经在模拟器和我的实际 Android 手机中尝试过,但都不起作用。Logcat 失败时不会产生错误。如果有人有这方面的经验并且可以提供一些示例代码/关于我的代码为什么不起作用的见解,我将非常感激......非常感谢!