전 포스트에서 AbstractAccountAuthenticator 의 addAccount 를 구현해서 아이디를 추가하는것을 해 보았습니다.

그런데 실제로 서비스에서는 “Add account” 를 누르면 아이디 비밀번호를 묻는 UI 가 나와야 정상일 것입니다.

그래서 안드로이드는 이를위해 AccountAuthenticatorActivity 를 제공합니다.

 

여기서 쓰는 UI 는 아이디와 비밀번호를 입력받는 EditText 가 두개있고 login 과 cancel 버튼이 있는 레이아웃 입니다.

여기서 쓰는 xml 은 아래와 같습니다.

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<ScrollView android:layout_height="wrap_content"
android:id="@+id/ScrollView01"
android:layout_weight="1"
android:layout_width="fill_parent">

<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">

<EditText android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/EditText_id"
android:hint="아이디">
</EditText>
<EditText android:inputType="textPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/EditText_password"
android:hint="비밀번호">
</EditText>
</LinearLayout>
</ScrollView>

<LinearLayout android:id="@+id/LinearLayout02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#c6c3c6">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Button_login"
android:text="Login">
</Button>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Button_cancel"
android:text="Cancel">
</Button>
</LinearLayout>
</LinearLayout>

 

매니페스트에는 아래와 같이 activity 를 추가합니다.

<activity android:name=".authenticator.AuthenticatorActivity" 
android:theme="@android:style/Theme.Dialog">
</activity>

 

이제 AuthenticatorActivity 소스를 보면 아래와 같습니다.

package net.cranix.android.cranixsyncsample.authenticator;

import net.cranix.android.cranixsyncsample.Constants;
import net.cranix.android.cranixsyncsample.R;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class AuthenticatorActivity extends AccountAuthenticatorActivity {
private EditText textId;
private EditText textPassword;

private AccountManager accountManager;

@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);

final Button btnLogin = (Button) findViewById(R.id.Button_login);
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doLogin();
}
});

final Button btnCancel = (Button) findViewById(R.id.Button_cancel);
btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doCancel();
}
});

textId = (EditText) findViewById(R.id.EditText_id);
textPassword = (EditText) findViewById(R.id.EditText_password);
accountManager = AccountManager.get(this);
}

private void doLogin() {
final String id = textId.getText().toString();
final String password = textPassword.getText().toString();
final Account account = new Account(id,Constants.ACCOUNT_TYPE);
if (accountManager.addAccountExplicitly(account, password, null)) {
final Intent intent = new Intent();
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, id);
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);

setAccountAuthenticatorResult(intent.getExtras());
setResult(RESULT_OK,intent);
finish();
}
else {
doCancel();
}
}
private void doCancel() {
setResult(RESULT_CANCELED);
finish();
}
}

 

AccountAuthenticatorActivity 는 일반 Activity 와 다른점이 두가지 있습니다.

   1. 액티비티를 띄울때 intent 의 extra 로 AccountAuthenticatorResponse 객체를 담고 있어야 함.

   2. “setAccountAuthenticatorResult(bundle)” 메소드로 결과를 돌려줘야함.

 

위의 doLogin 함수에서 setAccountAuthenticatorResult 메소드를 쓰는것을 볼 수 있습니다.

이제 이 Activity 를 띄우기 위해서 지난번에 만들었던 Authenticator 클래스를 수정해 봅시다.

 

public class Authenticator extends AbstractAccountAuthenticator {
private Context context;
public Authenticator(Context context) {
super(context);
this.context = context;
}
@Override
public Bundle addAccount(AccountAuthenticatorResponse response,
String accountType, String authTokenType,
String[] requiredFeatures, Bundle options)
throws NetworkErrorException {

Intent intent = new Intent(context,AuthenticatorActivity.class);

intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);

final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}

...
...
}

 

여기서 intent 의 extra 로 response 를 넣어서 만든후에 bundle 에 담아서 넘겨주는것을 볼 수 있습니다.

이렇게 하면 자동으로 인텐트에 지정된 Activity 가 뜨게 되면서 처리를 위임하게 됩니다.

 

이제 “Add account” 누른후 자신의 계정을 클릭하면 아래와 같은 화면이 나오는 것을 볼 수 있습니다.

image

 

 

이제 껍데기는 다 만들었습니다.

이제 이 아이디를 이용해서 sync 를 구현하면 됩니다.

sync 구현 역시 새로운 서비스를 만들어야 하는데 이는 다음번에 알아보도록 하겠습니다.

by cranix 2010.12.24 15:03