到目前为之,我们讨论了如何访问 Google APIs,其中使用到了Google的账户和用户信息。如果您自己有在线服务,但是没有Google账户和用户,这种情况下您还如何办呢?很明显如果用户能够在设备上安装一种新的账户类型是个不错的方案。这节课程将会告诉你如何实现自定义账户类型,自定义账户类型使用起来和Android内置账户的使用方式是一样的。
实现您的自定义 Account 代码
首先需要提供一种获取用户身份信息的方法。最简单的方式就是现实一个带有用户名和密码输入框的对话框。如果要求安全级别比较高的话,您可以使用动态口令甚至扫描用户视网膜。不管使用何种方式,你都有实现如下功能:
- 收集用户身份信息
- 向服务器验证收集到的信息
- 在设备上存储用户凭证信息
可以通过一个 activity 来实现这些功能,我们称这个Activity为 身份认证Activity。
因为需要和 AccountManager
交互,身份认证Activity 和普通的Activity 要求是不一样的。为了让开发者更方便的使用,Android系统提供了一个包装类 AccountAuthenticatorActivity
,您可以直接继承这个类来实现您的自定义认证功能。
您如何在身份认证Activity中实现前两个需求是由您自己决定的(如果要是只有一种方式去收集和认证用户信息的话 就不叫“自定义”账户类型了,对吧!)。第三个需求有一个典型的简单实现,如下所示:
1
2
|
final
Account account =
new
Account(mUsername, <em>your_account_type</em>);
mAccountManager.addAccountExplicitly(account, mPassword,
null
);
|
做好账户信息的安全工作!
值得重点注意的是: AccountManager
不是一个加密服务业不是一个密码守卫者。它只是保存了您传递给它的用户凭证信息并且是 明文 保存的。在大多数的设备中,这些内容都保存在数据库中,并且需要Root权限才能访问这些信息,所以这问题不是很严重。但是如果在一个已经被Root的设备中,任何人通过adb
工具都可以访问这些信息。
需要注意的是,您不应该把用户的真实密码当做参数调用 AccountManager.addAccountExplicitly()
这个函数,您应该使用一个加密后的安全Token来抵制密码破解攻击 从而避免类似CSDN密码泄露事件的发生。如果您的用户使用的是很有价值的服务(比如和金钱相关的 — 支付宝等),您更应该使用类似的手段来加密用户的身份凭证信息。
注意: 当涉及到安全问题的时候,请遵守“Mythbusters 流言终结者”规则:不用在家尝试!在实现您的自定义账户代码之前请咨询专业的安全机构。
关于安全问题的免责声明已经很清楚了,现在言归正传。
继承 AbstractAccountAuthenticator 类
想要把 AccountManager
应用到您的自定义账户类型中,您必需实现一个 AccountManager
中要用到的接口,也就是 authenticator class 身份认证类.
最简单的方式实现authenticator class是继承 AbstractAccountAuthenticator
类并实现里面的抽象函数。如果您已经看过了前一节课程,那么您应该已经对 AbstractAccountAuthenticator
类中的抽象函数比较熟悉了。就是您在前面的课程中获取账户信息和授权Token所调用的函数。
实现一个 authenticator class 需要分开实现多个函数。首先,AbstractAccountAuthenticator
有七个抽象函数,您必需实现他们;其次,你需要在Manifest文件中添加一个intent filter ("android.accounts.AccountAuthenticator"
,在下一节会有示例代码);最后 ,您必需通过两个XML文件来指定自定义账户的名称和系统图标以及其他相关信息。
在 AbstractAccountAuthenticator
类的JavaDoc文档中您可以发现详细的手把手教程教您如何实现一个成功的authenticator class。在
SampleSyncAdapter 示例中也有一个简单的实现。
如果您查看了 SampleSyncAdapter 的代码,您会发现有好几个函数都在返回的Bundle中添加一个Intent。这是用来启动自定义认证Activity的Intent。如果您的认证Activity需要其他特殊的初始化参数的话,您可以通过函数Intent.putExtra()
把这些参数的值设置到那个Intent中。
创建一个授权认证服务
现在您已经有一个 authenticator class了,您需要一个地方来运行她。账户认证服务需要在多个程序中使用(并在后台运行),所以在Service
中来运行 authenticator class是非常适合的。我们称这个Service为 authenticator service(身份认证服务)
您的 authenticator service 可以非常简单。只需要在 onCreate()
函数中创建您的 authenticator class ,然后在onBind()
函数中调用函数 getIBinder()
即可。
SampleSyncAdapter 示例项目中演示了如何实现一个 authenticator service。
不用忘了在您的Manifest文件中添加 <service>
标签以及AccountAuthenticator的Intent filter和声明 account
authenticator:
1
2
3
4
5
6
7
|
<
service
...>
<
intent-filter
>
<
action
android:name
=
"android.accounts.AccountAuthenticator"
/>
</
intent-filter
>
<
meta-data
android:name
=
"android.accounts.AccountAuthenticator"
android:resource
=
"@xml/authenticator"
/>
</
service
>
|
发布您的服务
该做的都已经完成了,现在系统已经可以识别您的账户类型了,在 “Google” 和 “Corporate.” 账户类型旁边。您可以在 Accounts & Sync 设置页面中来添加您的账户了,然后其他程序就可以和别的账户类别一样来使用您的账户服务了。
当前,这都是在用户设备已经安装了您的账户类型的前提下。如果只有一个程序使用了这个服务,您可以把自定义账户认证服务绑定到这个程序中即可。但是如果您希望其他程序也使用您的账户服务,事情就变得有点麻烦了。您可不希望每个程序都绑定一个账户服务,这样的话系统中将会有很多个一样的服务在运行,这样不仅会浪费用户设备的存储空间也会浪费用户设备的内存。
可以把这个服务放到一个特别的APK文件中。当一个程序需要使用您的账户类型时,她可以检测系统是否已经安装了您的账户服务。如果没有的话,这个程序可以把用户引导到Android市场中来安装您的这个APK程序。虽然这样做第一次用户使用起来有点麻烦,但是和每次用户使用的时候都要输入用户名和密码相比还是很方便的。
原文: http://yunfeng.sinaapp.com/?p=283