无法让我的帐户显示在 Android 帐户中...任何人都可以看一下吗?
很多代码...我从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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我没有看到您的列界面文件。它定义您的自定义 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.