android账号与同步之账号管理

在android提供的sdk中,samples目录下有一个叫SampleSyncAdapter的示例,它是一个账号与同步的实例,比如Google原始的android手机可以使用Google账号进行数据的同步。具体

的比如你想实时同步你的通讯录到服务端,这时候你就可以通过这个实例来了解android提供的同步机制,从而实现自己的同步功能。

本片博文先介绍一下账号的管理部分。至于账号管理的代码主要是在authenticator包下的三个类里面,还有就是一个叫authenticator的xml文件。

AuthenticationService类

AuthenticationService是一个继承Service的服务,这个服务其实是提供给其他的进程使用的,它的Action为android.accounts.AccountAuthenticator,android系统会通过这个

Action找到它,并通过它来把我们自己的账号注册到“设置”中,其实这是一个AIDL的使用,它属于跨进程的调用。下面是manifest中的注册:

<service

android:name=".authenticator.AuthenticationService"

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>

这个Service会在onBind方法里返回一个IBinder给客户端进程,如下:

@Override

public IBinder onBind(Intent intent) {

if (Log.isLoggable(TAG, Log.VERBOSE)) {

Log.v(TAG, "getBinder()...  returning the AccountAuthenticator binder for intent "

+ intent);

}

return mAuthenticator.getIBinder();

}

Authenticator类

Authenticator是一个继承自AbstractAccountAuthenticator的类,AbstractAccountAuthenticator是一个虚类,它定义处理手机“设置”里“账号与同步”中Account的添加、删除和

验证等功能的基本接口,并实现了一些基本功能。AbstractAccountAuthenticator里面有个继承于IAccountAuthenticator.Stub的内部类,以用来对AbstractAccountAuthenticator的

远程接口调用进行包装。我们可以通过AbstractAccountAuthenticator的getIBinder()方法,返回内部类的IBinder形式,以便对此类进行远程调用,如上面代码onBind方法中的调

用。AbstractAccountAuthenticator的源码位置在frameworks\base\core\java\android\accounts目录下。

Authenticator只需要继承和实现AbstractAccountAuthenticator的几个方法就可以了,像我们所介绍的SampleSyncAdapter实例主要继承了两个方法,如下

//当在“设置”中添加账号时,会调用这个方法,跳转到添加账号页面

@Override

public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,

String authTokenType, String[] requiredFeatures, Bundle options) {

Log.v(TAG, "addAccount()");

//指定AuthenticatorActivity为添加账号的页面,下面会介绍。

final Intent intent = new Intent(mContext, AuthenticatorActivity.class);

intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);

final Bundle bundle = new Bundle();

bundle.putParcelable(AccountManager.KEY_INTENT, intent);

return bundle;

}

//当执行mAccountManager.blockingGetAuthToken(account,Constants.AUTHTOKEN_TYPE, NOTIFY_AUTH_FAILURE);时调用该方法。

@Override

public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,

String authTokenType, Bundle loginOptions) throws NetworkErrorException {

Log.v(TAG, "getAuthToken()");

// 通过blockingGetAuthToken方法传来的Constants.AUTHTOKEN_TYPE

if (!authTokenType.equals(Constants.AUTHTOKEN_TYPE)) {

final Bundle result = new Bundle();

result.putString(AccountManager.KEY_ERROR_MESSAGE, "invalid authTokenType");

return result;

}

final AccountManager am = AccountManager.get(mContext);

final String password = am.getPassword(account);

if (password != null) {

final String authToken = NetworkUtilities.authenticate(account.name, password);

if (!TextUtils.isEmpty(authToken)) {

//如果已经到服务器验证过账号并保存到AccountManager中

final Bundle result = new Bundle();

result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);

result.putString(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);

result.putString(AccountManager.KEY_AUTHTOKEN, authToken);

return result;

}

}

//如果没有到服务器验证过账号并保存到AccountManager中,则重新倒添加账号页面中验证。

final 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);

final Bundle bundle = new Bundle();

bundle.putParcelable(AccountManager.KEY_INTENT, intent);

return bundle;

}

AuthenticatorActivity类

AuthenticatorActivity是一个继承自AccountAuthenticatorActivity的activity,AccountAuthenticatorActivity的源码也是在frameworks\base\core\java\android\accounts目录

下。AuthenticatorActivity主要的一个方法是handleLogin(View view),当点击Sign in按钮时会调用该方法,该方法会启动一个异步任务来请求服务器验证用户账号。验证成功后有

一个重要的方法:

/**

* Called when response is received from the server for authentication

* request. See onAuthenticationResult(). Sets the

* AccountAuthenticatorResult which is sent back to the caller. We store the

* authToken that‘s returned from the server as the ‘password‘ for this

* account - so we‘re never storing the user‘s actual password locally.

*

* @param result the confirmCredentials result.

*/

private void finishLogin(String authToken) {

Log.i(TAG, "finishLogin()");

final Account account = new Account(mUsername, Constants.ACCOUNT_TYPE);

if (mRequestNewAccount) {

//直接向AccountManager添加一个帐户

mAccountManager.addAccountExplicitly(account, mPassword, null);

//设置让这个账号能够自动同步

ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true);

} else {

mAccountManager.setPassword(account, mPassword);

}

final Intent intent = new Intent();

intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mUsername);

intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);

setAccountAuthenticatorResult(intent.getExtras());

setResult(RESULT_OK, intent);

finish();

}

authenticator.xml

在上面的AuthenticationService注册中有个meta-data的名字为android.accounts.AccountAuthenticator,它所指向的xml文件是authenticator.xml,其内容如下:

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"

android:accountType="com.example.android.samplesync"

android:icon="@drawable/icon"

android:smallIcon="@drawable/icon"

android:label="@string/label"

/>

其中账户类型为com.example.android.samplesync,就是Constants.ACCOUNT_TYPE的值。这个有点像widget,需要一个xml提供你想要的信息。

android账号与同步之账号管理

时间: 2024-08-29 03:52:47

android账号与同步之账号管理的相关文章

android账号与同步之同步实现

上一篇博文我先介绍了账号与同步的账号管理,这篇就介绍一下还有一部分.就是android给提供的sync同步机制的使用. 事实上sync机制的使用和上一篇博文中介绍的账号管理非常类似,也是基于binder机制的跨进程通信.首先它须要一个Service.这个服务提供一个Action给系统以便系统能找到它.然后就是继承和实现AbstractThreadedSyncAdapter.此类中包括实现了ISyncAdapter.Stub内部类.这个内部类封装了远程接口调用,这个类getSyncAdapterB

android账号与同步之发起同步

上一篇博文我介绍了账号与同步的同步实现过程,其中提供了一个工系统进程调用的服务,那么这个服务到底是怎么被启动和使用的呢?这篇博文我就大体梳理一下启动过程. 其实作为一个一般开发人员,我们只要知道要想知道被监听的ContentProvider有变动,首先那个ContentProvider必须使用ContentResolver.notifyChange(android.net.Uri, android.database.ContentObserver, boolean)这个方法来通知我们.我们知道这

一步一步教你在 Android 里创建自己的账号系统(二)--同步数据以及设计账号页面

大家如果喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 在前一篇文章中(一步一步教你在 Android 里创建自己的账号系统(一)),我向大家介绍了如何在 Android 系统中创建自己的账户系统,接下来我会向大家详细介绍一下如何使用账户系统. (一)同步数据 通常而言,我们会在两种情况下使用我们的账号系统: (1)登陆验证 登陆验证其实是一个很实用的功能,试

设计一个Bank类,银行某账号的资金往来账管理

设计一个Bank类,实现银行某账号的资金往来账管理,包括建账号.存入.取出等.Bank类包括私有数据成员top(当前指针).date(日期).money(金额).rest(余额)和sum(累计余额).另有一个构造函数和3个成员函数bankinO(处理存入账).bankout()(处理取出账)和disp( )(出明细账). [知识点]:2.2  2.3 [参考分]:25分 [难易度]:B 实现案例: /* 2017年8月19日23:03:58 */ #include<iostream> clas

RHEL账号总结一:账号的分类

账号是一种用来记录单个用户或者多个用户的数据.RHEL中每一个合法的用户都必须拥有账号,才能使用RHEL. 在RHEL上的账号可以分为两类: 用户账号:用来存储单一用户的数据,你也可以使用一个用户账号来存储某一个用户的数据. 组账号:用来存储多个用户的信息,每一个组账号都可以记录一组用户的数据. 在RHEL系统中,每一个种账号可以建立4294967296个:也就是说一台RHEL系统,最多可以建立42亿多个用户账号,以及42亿多个组账号. 我们可以把RHEL的所有账号依照下面两种方法进行分类. 1

(android文档原创翻译)管理Activity的生命周期&lt;一&gt;

(英文原文链接地址) 1.启动你的Activity 不同其它的应用程序通过main()方法来启动,android系统是按照一定的顺序通过调用其生命周期(lifecycle)的回调方法来启动或者结束一个activity.本节简要介绍了Activty的最为重要的生命周期,并且示意了怎样处理一个Activity的生命周期. 理解什么叫做生命周期的callbacks 在Activity的生命周期中,android系统会按顺序调用一系列类似于金字塔形排列的生命周期方法,即activity生命周期的每个阶段

iOS “弱账号” 暗转 “强账号”

一.背景 由于某些历史原因,我们产品中50%以上活跃用户是弱账户.即 客户端按照某种规则生成的一个伪id 存在keychain 里,作为这个用户的唯一标识,实现快速登录.正常情况下是不会有问题. 最近,公司的apple 账号需要更换,这样我们的iOS app 需要从老账号 迁移到 新账号上,苹果也提供了迁移功能.那么,问题来了,apple 账号的变换 会导致 teamid 的变换,而keychain里面的存储 key与 teamid 有所关联. 说白了,teamid 变了,你keychain老账

Android开发之AudioManager(音频管理器)详解

AudioManager简介: AudioManager类提供了访问音量和振铃器mode控制.使用Context.getSystemService(Context.AUDIO_SERVICE)来得到这个类的一个实例. 公有方法: Public Methods int abandonAudioFocus(AudioManager.OnAudioFocusChangeListenerl) 放弃音频的焦点. void adjustStreamVolume(int streamType, int dir

Android学习路线(十一)管理Activity的生命周期

当一个用户进入,退出,再次进入你的应用时,你的应用中的Activity 会在它的生命周期的各个状态下切换.例如,当你的activity第一次启动,它出现在系统的前方接受用户的焦点.在这个过程中,Android系统调用了一系列的生命周期方法来设置UI和其他组件.如果用户执行了一个操作,启动了另一个activity或者切换到其它应用中,你的activity会移动到后台(这时activity已经不可见,但是它的实力和状态都保持不变),系统会调用另外的一些生命周期方法. 通过这些生命周期方法,你可以声明