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给client进程。例如以下:
@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)) {
//假设已经到server验证过账号并保存到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;
}
}
//假设没有到server验证过账号并保存到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 inbutton时会调用该方法。该方法会启动一个异步任务来请求server验证用户账号。验证成功后有
一个重要的方法:
/**
* 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账号与同步之账号管理的更多相关文章
- android账号与同步之同步实现
上一篇博文我先介绍了账号与同步的账号管理,这篇就介绍一下还有一部分.就是android给提供的sync同步机制的使用. 事实上sync机制的使用和上一篇博文中介绍的账号管理非常类似,也是基于binde ...
- android账号与同步之发起同步
上一篇博文我介绍了账号与同步的同步实现过程,当中提供了一个工系统进程调用的服务,那么这个服务究竟是怎么被启动和使用的呢?这篇博文我就大体梳理一下启动过程. 事实上作为一个一般开发者,我们仅仅要知道要想 ...
- 将Sql Server迁移到Always on集群 - 账号的同步
Always on环境的建立,网上资料很多,主要是windows集群的建立以及Sql Server Always on的建立,略 容易忽略的是Sql server账号同步问题(Always on能实现 ...
- LINUX 学习笔记 账号与群组的管理
LINUX 账号与群组的管理 UID:UserID 保存文件:/etc/passwd GID:GroupID 保存文件:/etc/group /etc/passwd 文件结构 一行代表一个账号,里面还 ...
- RHEL账号总结一:账号的分类
账号是一种用来记录单个用户或者多个用户的数据.RHEL中每一个合法的用户都必须拥有账号,才能使用RHEL. 在RHEL上的账号可以分为两类: 用户账号:用来存储单一用户的数据,你也可以使用一个用户账号 ...
- iOS “弱账号” 暗转 “强账号”
一.背景 由于某些历史原因,我们产品中50%以上活跃用户是弱账户.即 客户端按照某种规则生成的一个伪id 存在keychain 里,作为这个用户的唯一标识,实现快速登录.正常情况下是不会有问题. 最近 ...
- ebay如何确定同一电脑登陆了多个账号,以及同一账号登陆过多台电脑
转自hilton 的BLOG http://jimqu.blog.51cto.com/105370/654691 一切要从ebay的买家保护说起 ebay作为一个电子商务平台,之所以可以汇聚如此众多的 ...
- Java并发框架——同步状态的管理
整个AQS框架核心功能都是围绕着其32位整型属性state进行,一般可以说它表示锁的数量,对同步状态的控制可以实现不同的同步工具,例如闭锁.信号量.栅栏等等.为了保证可见性此变量被声明为volatil ...
- [转]10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程
摘要: # 10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程 ## 背景说明 > 2016年的双11在淘宝上买买买的时候,天猫和优酷土豆一起做了联合促销,在天猫 ...
随机推荐
- swift potocol 作为参量时函数的派发顺序
1.检查protocol本体是否声明调用函数: 2.如果没有,检查protocol扩展是否有该函数:如果扩展中也没有,报错: 3.如果本体声明了函数,使用动态派发机制进行派发:扩展中的实现位于最末位.
- iview构建 初始化的时候不要装ESlint 太烦人了
iview构建 Node.js Vue(全局安装) npm install -g vue-cli npm install vue-cli 问题:发现如果不全局安装VUE-cli,\n在它初始化的时候, ...
- 卸载钩子 UnhookWindowsHookEx
The UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindow ...
- http和socket
大多数情况下都是使用Http协议做网络通信的,少数情况下,如扣扣之类的即时通讯,就是用Socket建立长链接 Http一般都是短连接的,即客户端和服务端通讯一次后,服务端就关闭连接 Socket是长连 ...
- js中5中继承方式分析
//1.借用式继承 把sup的构造函数里的属性方法克隆一份sub实例对象 function Super(){ this.val = 1; this.fun1 = f ...
- Linux网络配置出现的问题
网络连接 : 选择桥接模式进入字符界面后,管理员登入后 ifconfig显示eth0和ol,但是不显示静态IP地址,即无inet.地址.广播.掩码 解决方案: 1.使用sudo dhclient e ...
- 常见的Redis问题?
Redis的那些最常见面试问题[转] 1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.Reids的特点 Redis本质上是一个Key-Value类型的内存数据 ...
- awk输出指定列
awk '{print $0} file' #打印所有列awk '{print $1}' file #打印第一列 awk '{print $1, $3}' file #打印第一和第三列 cat fil ...
- ResNet,DenseNet
目录 ResNet BOOM Why call Residual? 发展史 Basic Block Res Block ResNet-18 DenseNet ResNet 确保20层能训练好的前提下, ...
- selenium--driver.switchTo()-----转
https://www.cnblogs.com/clairejing/p/9499223.html 在自动化测试中,会遇到多窗口.多iframe.多alert的情况.此时,会使用driver.swit ...