Android开发(39) 账户管理器概述

账户管理器概述

这个类提供了访问到 用户在线账户的集中式注册中心 的能力。用户为每账户输入一次 认证信息(credentials,包含用户名和密码),过过 点击一次(one-click)完成认证的方式,授权应用程序(app)访问 在线的资源。不同的服务具有不同的处理账户的认证的方式,而 Account Manager 使用了插件化的认证器模块 对应不同的账户类型。认证器(它由第三方组织编写)处理 验证账户认证信息的具体实际内容。并且保存账户信息。比如 谷歌,facebook,和微软每个都拥有他们自己的认证器。
许多服务支持 关于单一授权标记(authentication token,简写为auth token) 的一些概念,它常常被用于验证 向服务发出的不包含真实密码的授权请求。而auth token 常常被创建于独立包含用户认证信息(用户名和密码)的请求。AccountManager可以为应用程序生成认证标记(auth token),那么应用程序不在需要去直接处理密码。autho token常常可重用和被AccountManager缓存,但是被必须周期性刷新。当停止工作的时候,应用程序使得auth token无效化,以让auth token知道去重新生成它们。 应用程序访问服务通常通过下面几个步骤:

获得一个 AuccountManager的实例,通过 get(Context)方法。
列出可用的账户,使用getAccountsByType(String) 或者 getAccountsByTypeAndFeatures(String, String[],AccountManagerCallback, Handler).一般应用程序会对 一种指定的类型 的账户 感兴趣,它是认证器的标识。账户特性被用于标识特定账户的子类型和能力。账户类型和特性这两个是认证器规范字符串,并且必须被应用程序所知道,关于协调它们的首选认证器。
选择一个或者多个可用的账户,可能的话询问用户他们的偏好。如果没有匹配的账户可以使用,addAccount(String, String, String[], Bundle, Activity, AccountManagerCallback, Handler) 将会被调用,提示用户创建一个适当类型账户
重要的:如果应用正在使用预先被记忆的账户选项,它必须确保账户仍然存在于一个被 通过 getAccountsByType(String)返 回的账户列表。为一个账户请求一个认证标记 不再导致 在设备结果中的“一个未定义的失败”。
使用auth token构建请求。auth token的表单,请求的格式,和使用的协议都特定于你要访问的服务。应用可以使用任何网络和协议库。
重要的:如果请求失败于一个“授权错误”,那么可能 缓存的auth token过期并且不再被服务端信任。应用必须调用 invalidateAuthToken(String, String)去移除auth token的缓存,另外请求将继续失败! 在使得auth token无效后, 立即返回到上面的“请求一个auth token”步骤。如果是第二次出处理失败了,那么它将被当做一次诚恳的认证失败来对待并 且通知用户或做其他适当处理。
一些AccountManager方法可能需要与用户交互,提示用户认证信息,呈现可选项,或者询问用户去添加账户。调用者可以选择是否允许AccountManager去直接启动必要的用户接口并且等待用户,或者返回一个intent,它是调用者可以启动接口。或者一些情况下,安装一个通知,它是用户可以选择去启动接口。让AccountManager直接启动接口,调用者必须提供当前 前端的Activity的Context.

 

许多AccountManager方法以 AccountManagerCallback 和 Handler作为参数。这些方法立即返回并且异步启动。如果一个回调被提供,那么run(AccountManagerFuture) 将在Handler的线程上被调用。结果被重新取得,是通过 “返回值”AccountManagerFuture 的 getResult()方法(也可以通过回调方法获得)。这个方法等待操作完成(如果需要的话)并且两者之一:返回结果或者 在操作过程中发生错误抛出异常。要使 请求 同步执行,通过方法接收到 future后立即调用 getResult()即可,不再需要提供回调。

 

请求可能被阻塞,包括getResult()在内,必须保证 从不在主线程被调用。如果在主线程被使用,那些操作将抛出IllegalStateException异常 。

AccountManager的常用方法

为指定账户设定密码

mAccountManager.setPassword(account, mPassword);

添加账户到 账户中心

final Account account = new Account(mUsername, Constants.ACCOUNT_TYPE);
mAccountManager.addAccountExplicitly(account, mPassword, null);

获得authToken

final String authtoken = mAccountManager.blockingGetAuthToken(account,
Constants.AUTHTOKEN_TYPE, NOTIFY_AUTH_FAILURE);

获得用户数据

String markerString = mAccountManager.getUserData(account, SYNC_MARKER_KEY);

AbstractAccountAuthenticator 概述

这是一个抽象的基类,用于创建账户管理器(AccountAuthenticators)。为了成为一 个 认证器,一个类必须继承该类,提供抽象方法的实现,并且写一个服务(service),
在被ACTION_AUTHENTICATOR_INTENT作为action的intent调用时,在该服务的 onBind (android.content.Intent) 方法实现中,直接返回getIBinder() 的返回值结果。在
AndroidManifest.xml 文件中,这个服务必须指定下面的 intent过滤器(intent filter )和元数据标记。

<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />

注意:ACTION_AUTHENTICATOR_INTENT其实是个常量,等于字符串 android.accounts.AccountAuthenticator,其实就是和上面这个intent filter的过 滤器action相同。

上面的xml描述中,android:resource 属性必须指向一个资源文件,像下面这样:

<account-authenticator 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="typeOfAuthenticator"
    android:icon="@drawable/icon"
    android:smallIcon="@drawable/miniIcon"
    android:label="@string/label"
    android:accountPreferences="@xml/account_preferences"
/>

使用你自己的资源替换 icon 和 label 属性指向的值。android:accountType 属性必须是个字符串,它唯一标识了你的 认证器,并且和 用户使用AccountManager 调用时
指定的字符串相同,同时 和你的账户类型(account type)一致。 android:icon的一个使用者是在 “账户和同步”设置页,android:smallIcon的一个使用者是在 联系人
应用程序的标签面板。

android:accountPreferences属性指向一个 首选项屏幕设置的xml配置文件 (PreferenceScreen xml ),它包含了一个PreferenceScreen 的列表,可以层级嵌套。
它可以被调用以管理认证器。示例如下:

<PreferenceScreen 
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/title_fmt" />
    <PreferenceScreen
    android:key="key1"
    android:title="@string/key1_action"
    android:summary="@string/key1_summary">
        <intent
            android:action="key1.ACTION"
            android:targetPackage="key1.package"
            android:targetClass="key1.class" />
    </PreferenceScreen>
</PreferenceScreen>

一些抽象方法的标准实现模式,像下面这样:

  • 如果为 认证器 提供的参数是足够的,到达了完全的满意,这时将会这样做(will do so )并且返回一个包含了结果的Bundle。
  • 如果 认证器 需要 从用户那里收集信息才能达到满意,这时,将创建一个intent打开 “提示用户信息的activity”,并且完成该请求。这个intent必须返回一个包含了 指定key名称为 KEY_INTENT 的 Bundle.当完成的时候,这个activity需要返回final修饰的结果。

这个intent应该使用key指示 KEY_ACCOUNT_MANAGER_RESPONSE来包含AccountAuthenticatorResponse。这个activity在结束时必须调用 onResult(Bundle) 或者 onError(int, String) 。
如果认证器不能同步处理请求,并且返回一个结果。那么当完成请求时,它可以选择返 回null和使用 AccountManagerResponse 去发送结果。
后续的关于 每个抽象认证器方法 的描述,将不描述 可能的异步原生请求处理,而将描述输入参数和期望结果来替代。

当写一个activity去满足那些请求,一种方式,必须在activity关闭时(或者任何其他情况下activity的作者认为是一个正确的时间去响应时),通过 AccountManagerResponse 并且通过响应返回结果。AccountAuthenticatorActivity 用于处理这些,那么当写activity去处理这些请求时,我们可以去继承(extend) 它。

AccountAuthenticatorActivity概述

这是一个抽象的用于实现activity的基类,常被用于帮助 抽象认证器 (AbstractAccountAuthenticator)的具体实现(implement)。如果 抽象认证器AbstractAccountAuthenticator 需要使用一个activity去捕获请求,这是它可以 让一个activity来继承AccountAuthenticatorActivity。 抽象认证器AbstractAccountAuthenticator 传递响应到intent的方法像下面这样:

intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);

这个 activity设置(指定)结果时,结果(result)被传递到响应通过 setAccountAuthenticatorResult(android.os.Bundle) 方法。当activity结束时,这个结果将被发送作为 请求的结果。如果这从未被设置或者设置为null,那么 错误 ERROR_CODE_CANCELED 将会在响应上被调用。

注意: 账户认证器通过intent调用 这个activity,通过intent传递参数:

intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); 传递一个 账户认证器响应到 这个activity,作为参数,而这个activity将处理具体实现,处理完毕后,使用 
 setAccountAuthenticatorResult(android.os.Bundle) 来设置处理的结果。

AccountManagerFuture概述

一个AccountManagerFuture 表现了 异步的AccountManager调用的结果。它提供了一些方法用于判断计算是否完成,等待计算过程,和获得运算结果。当运算完成后,阻塞(如果需要的话)知道结果被准备好,结果只能被使用 get 方法获得。取消操作将被 cancel方法处理。额外的方法被提供为判断任务被正常完成或者被取消。一旦一个运算被完成,运算就不能被取消了。如果你为了可以取消的意图而不提供一个有用的结果的方式 来使用这个类,你可以声明 类似格式 Future<?> 的类型并且返回null作为相关任务的结果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容