たくさんのコード...これは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が失敗しても、エラーは発生しません。誰かがこれを経験していて、私のコードが機能しない理由についてサンプルコード/洞察を提供できるなら、私は本当に感謝しています...どうもありがとう!