Androidアカウントの追加の具体的な手順


転載も可能ですhttp://blog.csdn.net/lyz_zyx/article/details/73571927概要
私たちは携帯電話システムの設定に「アカウント」という機能があります.クリックすると、QQ、微信、メールボックスなど、私たちが知っているアプリがいくつか入っています.そうです.これがAndroidシステムが提供するアカウント同期機能です.サードパーティ製のAPPでは、この機能を使用して、データを一定時間サーバに同期できます.例えば、微信は現在のシステムに登録されている微信アカウントの情報、チャット記録を微信サーバに同期し、android原生システムではGoogleアカウントを使用してデータの同期を行うことができる.ちなみに、システムはアプリアカウントを同期させる際に、眠っているアプリのプロセスを活性化させることもあります.この点は後述します.では、次はアカウント同期のDemoを実現するために一歩一歩進みます.
アカウントサービスの作成
最初のステップでは、android.accounts.AccountAuthenticatorのIntentとしてactionのサービスを定義し、meta-dataのresourceプロパティで、Accountの基本的な表示情報を説明するxmlファイルを指定します.Android Mainifest.xmlには、次のようなコードが追加されます.
[html] view plain copy
  
     
         
     
     
  

authenticator.xml: [html] view plain copy
  
  

注意:
android:accountTypeはあなたのAccountのタイプを表しています.それは唯一でなければなりません.
ステップ2では、アカウントサービスを作成し、サービスのonBindでAbstraactAccountAuthenticatorのgetIBinder()を調整して、リモートコール用のIBinderを返します.
[java] view plain copy
public class AuthenticationService extends Service {  
    privateAuthenticationService.AccountAuthenticator mAuthenticator;  

    privateAuthenticationService.AccountAuthenticator getAuthenticator() {  
        if(mAuthenticator == null)  
           mAuthenticator = new AuthenticationService.AccountAuthenticator(this);  
        returnmAuthenticator;  
    }  

    @Override  
    public voidonCreate() {  
       mAuthenticator = new AuthenticationService.AccountAuthenticator(this);  
    }  

    @Nullable  
    @Override  
    publicIBinder onBind(Intent intent) {  
        returngetAuthenticator().getIBinder();  
    }  

    classAccountAuthenticator extends AbstractAccountAuthenticator {  


        publicAccountAuthenticator(Context context) {  
           super(context);  
        }  

       @Override  
        publicBundle editProperties(AccountAuthenticatorResponse response, StringaccountType) {  
            returnnull;  
        }  

       @Override  
        publicBundle addAccount(AccountAuthenticatorResponse response, String accountType,String authTokenType, String[] requiredFeatures, Bundle options) throwsNetworkErrorException {  
           return null;  
        }  

       @Override  
        publicBundle confirmCredentials(AccountAuthenticatorResponse response, Accountaccount, Bundle options) throws NetworkErrorException {  
           return null;  
        }  

       @Override  
        publicBundle getAuthToken(AccountAuthenticatorResponse response, Account account,String authTokenType, Bundle options) throws NetworkErrorException {  
           return null;  
        }  

       @Override  
        publicString getAuthTokenLabel(String authTokenType) {  
           return null;  
        }  

       @Override  
        publicBundle updateCredentials(AccountAuthenticatorResponse response, Accountaccount, String authTokenType, Bundle options) throws NetworkErrorException {  
           return null;  
        }  

       @Override  
        publicBundle hasFeatures(AccountAuthenticatorResponse response, Account account,String[] features) throws NetworkErrorException {  
           return null;  
        }  
    }  
}  

説明:
AbstractAccountAuthenticatorに継承される内部クラスAccountAuthenticatorをAuthenticationServiceクラスで定義し、AccountAuthenticatorクラスオブジェクトのgetIBinder()をAuthenticationServiceのonBindメソッドで返します.
この簡単な2つのステップでは、プログラムを実行した後、「設定」-「アカウント」-「アカウントの追加」のリストからappを見つけることができます.
図:
アカウントの追加
微信のように、現在の携帯電話の微信が登録されていない場合、アカウントリストで微信をクリックすると、自動的に登録微信のActivityに移動しますが、appをクリックすると空白にジャンプしてタスク操作がありません.それは、アカウントサービスを作成しただけで、アカウントを追加するコード処理が行われていないからです.
最初のステップでは、2つの必要な権限を宣言します.
[html] view plain copy
                           //           
               //           

ステップ2で、AuthenticatorActivityを追加します.
[java] view plain copy
public class AuthenticatorActivity extendsAppCompatActivity {  

    publicstatic final String ACCOUNT_TYPE ="project.test.com.myapplication.account.type";    // TYPE   account_preferences.xml  TYPE      
    privateAccountManager mAccountManager;  

    @Override  
    protectedvoid onCreate(Bundle savedInstanceState) {  
       super.onCreate(savedInstanceState);  
       setContentView(R.layout.activity_authenticator);  

       mAccountManager = (AccountManager)getSystemService(ACCOUNT_SERVICE);  
       Account[] accounts =mAccountManager.getAccountsByType(ACCOUNT_TYPE);   //                         , TYPE      
        if(accounts.length > 0) {  
           Toast.makeText(this, "          ",Toast.LENGTH_SHORT).show();  
           finish();  
        }  

        ButtonbtnAddAccount = (Button)findViewById(R.id.btn_add_account);  
        btnAddAccount.setOnClickListener(new View.OnClickListener() {  
           @Override  
           public void onClick(View v) {  
               Account account = new Account(getString(R.string.app_name),ACCOUNT_TYPE);  
               mAccountManager.addAccountExplicitly(account, null, null);     //           null    

               finish();  
            }  
        });  
    }  
}  

説明:
1、Activityで定義したメンバー変数ACCOUNT_TYPEは、現在のAPPでシステムアカウントの一意のIDを取得するために使用されています.これは前のaccount_preferences.xmlでも述べたように、2つの声明は一致しなければならない.
2、onCreateでシステムアカウントリストに追加したアカウントが私たちのアカウントに存在するかどうかを取得し、私たちのTYPEを識別し、存在表示が追加された場合、現在のページを終了します.
3、アカウントを追加したことがない場合は、ログイン操作をシミュレートし、操作が成功した後、AccountManagerのaddAccountExplicitlyメソッドを使用してシステムアカウントにアカウントを追加します.
ステップ3では、AccountAuthenticatorクラスのaddAccountメソッドにジャンプログインのActivityを追加します.
[java] view plain copy
@Override  
public Bundle addAccount(AccountAuthenticatorResponseresponse, String accountType, String authTokenType, String[] requiredFeatures,Bundle options)  
        throwsNetworkErrorException {  
    final Bundle bundle = new Bundle();  
    final Intent intent = new Intent(mContext, AuthenticatorActivity.class);  
    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,response);  
    bundle.putParcelable(AccountManager.KEY_INTENT, intent);  
    return bundle;  
}  

再度プログラムを実行し、「アカウントの追加」のクリックとシミュレーションのログイン後、「設定」-「アカウント」で、図のように、私たちのアプリにアカウントが追加されていることを確認します.
勘定科目データの同期
上記のアカウントの追加操作が完了したら、アカウントをクリックすると、図のようなページにジャンプします.
このページには、私たちのアプリのアイコンと名前がリストされているだけで、他の操作と私たちが予想していた同期機能はありません.次に、APPに同期されたサービスコードを追加します.
まず、android.content.SyncAdapterのIntentとしてactionのサービスを定義し、meta-dataのresourceプロパティで同期の基本表示情報を説明するxmlファイルを指定します.Android Mainifest.xml追加コードは次のとおりです.
[html] view plain copy
  
     
         
     
     
  

sync_adapter.xml:
[html] view plain copy
  
  

説明:
android:accountTypeはあなたのAccountのタイプを表しています.必ず前と一致してください.
Android:allowParallelSyncsがマルチアカウント同時同期をサポートしているかどうか
android:contentAuthority同期するContentProviderを指定
Android:isAlwaysSyncableすべてのアカウントのisSyncableを1に設定
Android:supportsUploading設定同期するにはnotifyChange通知が必要かどうか
Android:userVisible設定が「設定」に表示されるかどうか
ステップ2では、同期サービスを作成し、サービスのonBindでAbstractThreadedSyncAdapterのgetIBinder()を調整して、リモートコール用のIBinderを返します.
[java] view plain copy
public class SyncService extends Service {  

    privatestatic final Object sSyncAdapterLock = new Object();  
    privatestatic SyncAdapter sSyncAdapter = null;  

    @Override  
    public voidonCreate() {  
       synchronized (sSyncAdapterLock) {  
            if(sSyncAdapter == null) {  
               sSyncAdapter = new SyncAdapter(getApplicationContext(), true);  
            }  
        }  
    }  

    @Nullable  
    @Override  
    public IBinderonBind(Intent intent) {  
        returnsSyncAdapter.getSyncAdapterBinder();  
    }  

    classSyncAdapter extends AbstractThreadedSyncAdapter {  
        publicSyncAdapter(Context context, boolean autoInitialize) {  
           super(context, autoInitialize);  
        }  

       @Override  
        publicvoid onPerformSync(Account account, Bundle extras, String authority,ContentProviderClient provider, SyncResult syncResult) {  
            //TODO         
            // getContext().getContentResolver().notifyChange(AccountProvider.CONTENT_URI,null, false);        }  
    }  
}  

説明:
1.A b s t r actThreadedSyncAdapterに継承された内部クラスSyncAdapterをSyncServiceクラスで定義し、SyncAdapterクラスオブジェクトのgetIBinder()をSyncServiceのonBindメソッドで返します.
2、SyncAdapterクラスのonPerformSync方法はサーバーへのデータの同期を実現するコードであり、ここでは省略する
3つ目はsync_adapter.xmlでContentProviderが指定されているので、アップロード用のContentProviderを作成するのは当然です.
[html] view plain copy
  

[java] view plain copy
public class AccountProvider extends ContentProvider{  

    publicstatic final String AUTHORITY ="project.test.com.myapplication.account.provide";  
    publicstatic final String CONTENT_URI_BASE = "content://" + AUTHORITY;  
    publicstatic final String TABLE_NAME = "data";  
    publicstatic final Uri CONTENT_URI = Uri.parse(CONTENT_URI_BASE + "/" +TABLE_NAME);  

    @Override  
    publicboolean onCreate() {  
        returnfalse;  
    }  

    @Nullable  
    @Override  
    publicCursor query(Uri uri, String[] projection, String selection, String[]selectionArgs, String sortOrder) {  
        returnnull;  
    }  

    @Nullable  
    @Override  
    publicString getType(Uri uri) {  
        returnnull;  
    }  

    @Nullable  
    @Override  
    public Uriinsert(Uri uri, ContentValues values) {  
        returnnull;  
    }  

    @Override  
    public intdelete(Uri uri, String selection, String[] selectionArgs) {  
        return0;  
    }  

    @Override  
    public intupdate(Uri uri, ContentValues values, String selection, String[] selectionArgs){  
        return0;  
    }  
}  

説明:
ここでは同期データのプレゼンテーションにのみ使用し,ContentProviderを実際に操作していないので,実際の開発では自分で改善することができる.
最後に、同期を実行します.AuthenticatorActivityのシミュレーションログインコードを変更し、ログインが成功した後に自動同期に設定します.
[java] view plain copy
……  
Button btnAddAccount =(Button)findViewById(R.id.btn_add_account);  
btnAddAccount.setOnClickListener(newView.OnClickListener() {  
    @Override  
    public voidonClick(View v) {  
        Accountaccount = new Account(getString(R.string.app_name), ACCOUNT_TYPE);  
       mAccountManager.addAccountExplicitly(account, null, null);                          //           null    
        //       
        Bundle bundle= new Bundle();  
       ContentResolver.setIsSyncable(account, AccountProvider.AUTHORITY, 1);  
       ContentResolver.setSyncAutomatically(account, AccountProvider.AUTHORITY,true);  
       ContentResolver.addPeriodicSync(account, AccountProvider.AUTHORITY,bundle, 30);    //      30   
        //       
        //ContentResolver.requestSync(account, AccountProvider.AUTHORITY, bundle);  
       finish();  
    }  
});  

説明:
アカウント情報の同期には、自動同期という2つの方法があります.1つは、予め設定された時間間隔でAndroidシステムに自動同期データを完成させることです.ここで注意しなければならないのは、Android自体が同期による消費を考慮し、起動装置の回数を減らすため、ここで予め設定された時間は一定の正確さであり、システムは実際に内部で同期を必要とするアルゴリズム処理を行い、例えばできるだけすべての同期データをある時点に配置し、だから私たちが予め設定した時間値はただの参考にすぎません.もう1つの方法は手動同期であり、手動同期はアプリケーションでメソッドを呼び出して直接デバイスに通知し、システムにデータの同期を通知する.
追加したアカウントのリストから再度アプリをクリックすると、図のようになります.
同期ページの変更
追加したアカウントのリストで私たちのアプリをクリックしてカスタマイズしたページを表示したい場合は、
authenticator.xmlファイルを変更し、accountPreferencesプロパティを追加します.
[html] view plain copy
  
  

account_preferences.xmlファイル:
[html] view plain copy
  
  
     
     
         
     
  

APPを再度実行し、追加したアカウントのリストに私たちのAPPをクリックすると、図のような中間ページが表示されます.
ひっぱりきこう
一部のアプリでは、もちろん自分のプロセスができるだけ殺されないことを望んでいます.したがって、アカウント同期もその1つとして計算される様々なプロセスのアクティブ化方法が現れます.システムアカウントの自動同期は、特定の時間にAPPデータをサーバに同期するためです.上記の実装でも、ログインアカウントと同期アカウントデータの実行は、私たち自身のコードによって実現されるため、データの同期時に終了または完全に終了したAPPを再び活性化します.筆者は一部の携帯電話で私たちが今日紹介したDemoを検証したが、効果はやはり通じることが分かった.もちろん、国内の携帯電話メーカーの各種注文や去勢によって、一部の携帯電話が通じないこともありますので、自分で試してみる時間があります.これもAndroidシステムの小さな脆弱性です.アカウント同期機能を活用し、良好な開発信仰を身につけ、ユーザーの意思を尊重することを望んでいます.すべてのユーザーが関係のないアプリをバックグラウンドに常駐させたいわけではないからです.
まとめ
Androidアカウントの同期の実装手順を簡単に説明し、実証するために、より完全なアカウント同期の実装が必要であれば、Anroid SDKのsamplesディレクトリの下にSampleSyncAdapterというアカウントと同期の例を自分で検討してみましょう.また、上記のDemoソースはこちらをクリックしてダウンロードできます