[android] authenticator 관련 Tutorial |
참조 : http://cranix.net/346
http://cranix.net/347
http://cranix.net/349
http://cranix.net/350
Authenticator Service
-
안드로이드 설정의 Accounts & Sync 메뉴의 기능 제공을 위해서 필요하다.
-
@ Manifest
<service android:name=".authenticator.AuthenticationService"> <intent-filter> <action android:name="android.accounts.AccountAuthenticator" /> </intent-filter> <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" /> </service>
-
@ xml/authenticator.xml
<?xml version="1.0" encoding="utf-8"?> <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" android:accountType="com.test.test" android:icon="@drawable/icon" android:smallIcon="@drawable/icon" android:label="@string/app_name" />
-
@AuthenticationService.java
public class AuthenticationService extends Service { @Override public void onCreate() { // TODO Auto-generated method stub } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }
-
위와 같은 기본 세팅만 해놓아도 시스템에서 활용 가능한 Accounts 목록에 등록이 된다.
-
AuthenticationService 만 만든다고 만사 오케이는 아니다.
계정에 대한 어떤 Action 을 취할 때 할 행동을 정의해줘야 하는데, 이는 Authenticator 를 통해서 이루어진다.
-
@AuthenticationService.java
public class AuthenticationService extends Service { private Authenticator authenticator; @Override public void onCreate() { authenticator = new Authenticator(this); } @Override public IBinder onBind(Intent intent) { return authenticator.getIBinder(); }
-
@Authenticator.java
public class Authenticator extends AbstractAccountAuthenticator { public Authenticator(Context context) { super(context); // TODO Auto-generated constructor stub } @Override public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { // TODO Auto-generated method stub return null; } @Override public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException { // TODO Auto-generated method stub return null; } @Override public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { // TODO Auto-generated method stub return null; } @Override public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { // TODO Auto-generated method stub return null; } @Override public String getAuthTokenLabel(String authTokenType) { // TODO Auto-generated method stub return null; } @Override public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException { // TODO Auto-generated method stub return null; } @Override public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { // TODO Auto-generated method stub return null;
-
위의 override 함수들은 계정에 어떤 action 을 취했을 떄 system 에서 호출되는 함수들이다.
계정 및 동기화 ( Accounts & Sync ) 에서 예를 들어 계정추가가 가능하도록 하려면 addAccount 를 구현해주면 된다.
-
@Manifest
... <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> ...
-
@ Authenticator.java
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 { Account account = new Account("test",accountType); AccountManager manager = AccountManager.get(context); manager.addAccountExplicitly(account, "mypassword", null); return new Bundle(); } ... }
-
계정 추가는 permission 이 필요하기에 permission 을 주고, 그 다음 계정 추가 코드를 추가해주면 된다.
-
AccountAuthenticatorActivity 를 통해 UI 도 제공하기.
@ Authenticator.java
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; } ... }
-
@ AuthenticatorActivity.java
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(); } }
-
Activity 를 띄울 때 intent extra 로 AccountAuthenticatorResponse 객체를 담고 있어야 한다.
결과는 setAccountAuthenticatorResult( Bundle ) 을 통해 전달해야 한다.
기존 addAccount 에서 AuthenticatorActivity 로 처리를 위임한 것이다.
SyncAdapter 를 통해 Auto Sync 하게 하기.
SyncAdapter 는 구글 싱크가 일어날 때 자동으로 함께 Sync 처리해주는 부분이다.
SyncAdapter 는 예상했듯이 Service 로 이루어져 있다.
@ Manifest
... <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /> ... <service android:name=".syncadapter.SyncService"> <intent-filter> <action android:name="android.content.SyncAdapter" /> </intent-filter> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" /> </service> ...
@ xml/syncadapter.xml
<?xml version="1.0" encoding="utf-8"?> <sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" android:contentAuthority="com.android.contacts" android:accountType="com.test.test" android:supportsUploading="false" />
android:contentAuthority 는 sync 할 ContentProvider 를 지정한다.
android:supportsUploading false 는 서버로 uploading 은 하지 않고 downloading 만 되는 server 가 read only 의 형태가 된다.
-
@ SyncService.java
public class SyncService extends Service { private SyncAdapter syncAdapter; @Override public void onCreate() { super.onCreate(); syncAdapter = new SyncAdapter(this,true); } @Override public IBinder onBind(Intent arg0) { return syncAdapter.getSyncAdapterBinder(); } }
-
@ SyncAdapter.java
public class SyncAdapter extends AbstractThreadedSyncAdapter { public SyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); } @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { // TODO : Sync 처리 } }
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] face detect and cropper (0) | 2015.12.08 |
---|---|
[android] webview 에서 파일 업로드하기 (0) | 2015.12.07 |
[android] tv 앱 기본설정 (0) | 2015.12.04 |
[android] Shadow effect with custom shapes (0) | 2015.12.03 |
[android] ART 의 GC 이야기. (0) | 2015.12.02 |
댓글