无法让我的帐户显示在 Android 帐户中...任何人都可以看一下吗?

发布于 2024-10-21 13:31:53 字数 12293 浏览 5 评论 0原文

很多代码...我从Android的官方示例代码中得到了这个, SampleSyncAdapter

无论如何,这是代码。我没有包含同步类,我只是想让帐户显示出来并能够暂时创建。

Account Authenticator 类:

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;

public class AuthenticatorActivity extends 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();
    }
}

Manifest 包括以下内容:

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

Lot of code... I got this from Android's official sample code, SampleSyncAdapter

Anyways here is the code. I did not include the syncing classes, I just want to get the account to show up and be able to be created for now.

Account Authenticator class:

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 class:

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;

public class AuthenticatorActivity extends 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 class:

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();
    }
}

Manifest includes the following:

<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>

and...

    <activity android:name=".AuthenticatorActivity"
        android:label="Sync Tag Account!"
        android:theme="@android:style/Theme.Dialog"
        android:excludeFromRecents="true">

The xml file referenced in the service is here:

<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"/>

I know this is a lot of code... but I've become pretty desperate trying to find a result for this. From what I understand this should work just fine, but when I go to add an account it times out/crashes, or just doesn't show my app's account as an option to add. I've tried this both in the emulator and my actual Android phone, neither work. No errors are produced in Logcat when it fails. If anyone has experience with this and could provide some sample code/insight as to why my code isn't working, I'd really appreciate it... thanks a lot!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

两个我 2024-10-28 13:31:53

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

I don't see your columns interface file. It defines your custom MIME_PROFILE and which columns in the Data table your contact data is stored in.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文