Android2.0 SDK帶來的一個好東西就是你可以寫一個普通的同步供應商程式,并将其與系統的聯系薄,月曆等內建。唯一的問題是相關的文檔十分的少。還有一個糟糕的問題在于,如果你在某一個地方出了錯,Android系統就會崩潰重新開機。面臨如此挑戰,我依靠這稀少的文檔,以及很少的文章,還有Android地帶的一些代碼去建立了一個同步程式----Last.fm 。你想要知道怎麼去建立你自己的同步程式麼?讀下去吧
賬戶驗證
這裡定義了該賬戶如何在“賬号&同步”設定中出現的。一個賬号的的驗證需要3部分來實作:1. 一個從onBind方法傳回AbstractAccountAuthenticator 子類的一個服務2. 一個Activityt提供使用者輸入他們的憑據(賬号秘密資訊),一個xml檔案去描述賬号資訊展示給使用者時( an xml file describing how your account should look when displayed to the user.)同時,你也需要在android.mainfest.xml中添加<b>android.permission.AUTHENTICATE_ACCOUNTS</b><b>權限</b>
服務
AccountAuthenticatorService.java
1 <b>import</b> fm.last.android.LastFm;
2 <b>import</b> android.accounts.AbstractAccountAuthenticator;
3 <b>import</b> android.accounts.Account;
4 <b>import</b> android.accounts.AccountAuthenticatorResponse;
5 <b>import</b> android.accounts.AccountManager;
6 <b>import</b> android.accounts.NetworkErrorException;
7 <b>import</b> android.app.Service;
8 <b>import</b> android.content.Context;
9 <b>import</b> android.content.Intent;
10 <b>import</b> android.os.Bundle;
11 <b>import</b> android.os.IBinder;
12 <b>import</b> android.util.Log;
13
14 /**
15 * Authenticator service that returns a subclass of AbstractAccountAuthenticator in onBind()
16 */
17 <b>public</b> <b>class</b> AccountAuthenticatorService <b>extends</b> Service {
18 <b>private</b> <b>static</b> <b>final</b> String TAG = <b>"</b><b>AccountAuthenticatorService</b><b>"</b>;
19 <b>private</b> <b>static</b> AccountAuthenticatorImpl sAccountAuthenticator = <b>null</b>;
20
21 <b>public</b> AccountAuthenticatorService() {
22 <b>super</b>();
23 }
24
25 <b>public</b> IBinder onBind(Intent intent) {
26 IBinder ret = <b>null</b>;
27 <b>if</b> (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT))
28 ret = getAuthenticator().getIBinder();
29 <b>return</b> ret;
30 }
31
32 <b>private</b> AccountAuthenticatorImpl getAuthenticator() {
33 <b>if</b> (sAccountAuthenticator == <b>null</b>)
34 sAccountAuthenticator = <b>new</b> AccountAuthenticatorImpl(<b>this</b>);
35 <b>return</b> sAccountAuthenticator;
36 }
37
38 <b>private</b> <b>static</b> <b>class</b> AccountAuthenticatorImpl <b>extends</b> AbstractAccountAuthenticator {
39 <b>private</b> Context mContext;
40
41 <b>public</b> AccountAuthenticatorImpl(Context context) {
42 <b>super</b>(context);
43 mContext = context;
44 }
45
46 /*
47 * The user has requested to add a new account to the system. We return an intent that will launch our login screen if the user has not logged in yet,
48 * otherwise our activity will just pass the user's credentials on to the account manager.
49 */
50 @Override
51 <b>public</b> Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options)
52 <b>throws</b> NetworkErrorException {
53 Bundle reply = <b>new</b> Bundle();
54
55 Intent i = <b>new</b> Intent(mContext, LastFm.<b>class</b>);
56 i.setAction(<b>"</b><b>fm.last.android.sync.LOGIN</b><b>"</b>);
57 i.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
58 reply.putParcelable(AccountManager.KEY_INTENT, i);
59
60 <b>return</b> reply;
61 }
62
63 @Override
64 <b>public</b> Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) {
65 <b>return</b> <b>null</b>;
66 }
67
68 @Override
69 <b>public</b> Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
70 <b>return</b> <b>null</b>;
71 }
72
73 @Override
74 <b>public</b> Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) <b>throws</b> NetworkErrorException {
75 <b>return</b> <b>null</b>;
76 }
77
78 @Override
79 <b>public</b> String getAuthTokenLabel(String authTokenType) {
80 <b>return</b> <b>null</b>;
81 }
82
83 @Override
84 <b>public</b> Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) <b>throws</b> NetworkErrorException {
85 <b>return</b> <b>null</b>;
86 }
87 @Override
88 <b>public</b> Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) {
89 <b>return</b> <b>null</b>;
90 }
91 }
92 }
93
該驗證服務需要在Android.Mainfest.xml中使用中繼資料标簽定義一下。如下
Snippet from AndroidManifest.xml
1 <service android:name="AccountAuthenticatorService"
2 android:exported="true" android:process=":auth">
3 <intent-filter>
4 <action android:name="android.accounts.AccountAuthenticator" />
5 </intent-filter>
6 <meta-data android:name="android.accounts.AccountAuthenticator"
7 android:resource="@xml/authenticator" />
8 </service>
9
Xml檔案
賬号的xml檔案中定義了當應用程式與你的賬号互動的時候,應用程式将會看到的東西(是不是向國内其他應用程式使用QQ一些應用一樣,首先會有一個授權,詢問使用者目前的應用程式可以通路你的使用者的哪些資訊?------我的了解)其中包含了使用者可讀的名字,你所定義的系統賬号類型,圖示,對一個包含當使用者修改賬号時可以看到的PreferenceScreens 的xml檔案。
authenticator.xml
1 <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
2 android:accountType="fm.last.android.account"
3 android:icon="@drawable/icon"
4 android:smallIcon="@drawable/icon"
5 android:label="@string/app_name"
6 android:accountPreferences="@xml/account_preferences"/>
7
account_preferences.xml
1 <PreferenceScreen
2 xmlns:android="http://schemas.android.com/apk/res/android">
3 <PreferenceCategory
4 android:title="General Settings" />
5
6 <PreferenceScreen
7 android:key="account_settings"
8 android:title="Account Settings"
9 android:summary="Sync frequency, notifications, etc.">
10 <intent
11 android:action="fm.last.android.activity.Preferences.ACCOUNT_SETUP"
12 android:targetPackage="fm.last.android"
13 android:targetClass="fm.last.android.activity.Preferences" />
14 </PreferenceScreen>
15 </PreferenceScreen>
16
內建(putting it all together)
現在我們可以準備開始測試了。Android 賬号的設定部分并不能完好的捕捉異常。如果有地方出錯了,裝置會重新開機。最好的測試方式是運作模拟器後,運作DevTools,點選AcountsTester
<a href="http://hddev.blog.51cto.com/attachment/201108/30/3365350_131470518584Sm.png"></a>
你會看到一個新的賬号類型将會同系統内置的“Corporate”類型的賬号一樣,被添加到清單中。盡管從下拉清單中選擇你的賬号,然後點選增加按鈕,那麼,将會呈現一個你所做的登入框。經過驗證後 ,你的賬号将會出現在按鈕下邊的清單中。在這一點,使用系統的“Account&sync”設定去移除和修改賬戶應該是安全的。
準備好“Data & synchronization”的章節了麼?讓我們開始第二個章節吧。
本文轉自HDDevTeam 51CTO部落格,原文連結:http://blog.51cto.com/hddev/653349,如需轉載請自行聯系原作者