0

很多代码......我从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 失败时不会产生错误。如果有人有这方面的经验并且可以提供一些示例代码/关于我的代码为什么不起作用的见解,我将非常感激......非常感谢!

4

1 回答 1

0

我没有看到您的列接口文件。它定义了您的自定义 MIME_PROFILE 以及您的联系人数据存储在 Data 表中的哪些列。

于 2011-03-09T08:41:19.933 回答