-
private
void
finishAutoSetup() {
String email =
mEmai
lView
.getText().toString();
String password =
mPasswordView
< br>.getText().toString();
String[] emailParts = splitEmail(email);
String user = emailParts[0];
String domain = emailParts[1];
URI incomingUri =
null
;
URI
outgoingUri =
null
;
try
{
String userEnc =
URLEncoder.
encode
(user,
);
String passwordEnc =
URLEncoder.
encode
(password,
);
String incomingUsername =
mProvider
.
incomingUsernameTemplate
;
incomingUsername
=
eAll(
,
email);
incomingUsername = eAll(
,
userEnc);
incomingUsername = eAll(
,
domain);
URI incomingUriTemplate =
mProvider
.
incomingUriTemplate
;
incomingUri =
new
URI(eme(),
incomingUsername +
+ passwordEnc, t(),
t(),
null
,
null
,
null
);
String outgoingUsername = <
/p>
mProvider
.
outgoing
UsernameTemplate
;
URI outgoingUriTemplate = <
/p>
mProvider
.
outgoing
UriTemplate
;
if
(outgoingUsername !=
null
) {
outgoingUsername =
eAll(
,
email);
outgoingUsername =
eAll(
,
userEnc);
outgoingUsername =
eAll(
,
domain);
outgoingUri =
new
URI(eme(),
outgoingUsername +
+ passwordEnc,
t(), t(),
null
,
null
,
null
);
}
else
{
outgoingUri =
new
URI(eme(),
null
, t(),
t(),
null
,
null
,
null
);
}
if
(
mAccount
==
null
) {
mAccount
= Preferences.
getPreferences
(
this
).newAccount();
}
mAccount
< br>.setName(getOwnerName());
mAccount
.setEmail(email);
mAccount
.setStoreUri(ng());
mAccount
< br>.setTransportUri(ng());
mAccount
.setDraftsFolderName
(getString(.
special_mailbox_name_drafts
));
m
Account
.setTrashFolderName(getString(.<
/p>
special_mailbox_name_trash
))<
/p>
;
mAcc
ount
.setArchiveFolderName(getString(.
p>
special_mailbox_name_archi
ve
p>
));
//
Yahoo! has a special folder for Spam, called
if
(t().toLowerCa
se().endsWith(
)) {
mAccount
.setSpamFolderName(
);
}
else
{
mAccount
.setSpamFolderName(g
etString(.
special_mailbox_name_spam
));
}
mAccount
.setSentFolderName(g
etString(.
special_mailbox_name_sent
));
if
(ng().startsWith(
)) {
mAccount
.setDeletePolicy(Account.
DELETE_
POLICY_ON_DELETE
);
}
else
if
(ng().startsWith(
)) {
mAccount
.setDeletePolicy(Account.
DELETE_
POLICY_NEVER
);
}
// Check
incoming here. Then check outgoing in
onActivityResult()
AccountSetupCheckSettings.
actionCheckSe
ttings
(
this
,
mAccount
,
CheckDi
rection.
INCOMING
);
}
catch
(UnsupportedEncodingException enc) {
// This really shouldn't happen since
the encoding is hardcoded to
UTF-8
Log.
e
(K9.
LOG_TAG<
/p>
,
urlencode
username
or
password.
,
enc);
}
catch
(URISyntaxException use) {
/*
*
If there is some problem with the URI we give up
and go on to
*
manual setup.
*/
onManualSetup();
}
}
MIME
邮件的构成
MIME
消息(邮件,对应
k9mail
的
MimeMessage
类)
,由消息头
(对应
k9mai
的
MimeHeader
类)和消息体(
body
对应
k9mail
的
Body
接口)两大部分组成。邮件头中不
允许出现空行。邮件头包含了发件人、收件人、主题、时间、
MIME
版本、邮件内容的类型
等重要信息。每条信息称为一个域,由域名后加“
:
”和信息的内容构成,可以是一行,<
/p>
较长的也可以占用多行。
域的首行必须
“
顶头”
写,
即左边不能有空白字符
(空
格和制表符)
;
续行则必须以空白字符打头,且第一个空白字符
不是信息本身固有的,解码时要过滤掉。
邮件头信息中各个字段及其含义的说明如下表:
邮件体(
body
< br>)指的是邮件的内容,它的类型由邮件头的“
Content-
Type
”域指出,常
见的简单类型有
text/plain(
纯文本
)
p>
和
text/html(
超文本
)
。
multipar
t
类型是
MIME
邮件的精
髓,
对应
k9mail
的
MultiPart
类。
邮件体被分
为多个段或者多个部分,
对应
k9mail
的
Part
接口,每个段又包含段头和段体两部分,这两部分之
间也以空行分隔。
常
见
的
multipart
类
型
有
三
种
:
multipart/mixed,
multipart/related
和
multipart/alternative
。从它们的名称,不难推知这些类型
各自的含义和用处。它们之间的层
次关系如下图所示,
从中可以
看出,
如果在邮件中要添加附件,
必须定义
multipart/mixed
段;
如果存在内嵌资源,至少要定义
multipart/related
段;如果纯文本与超文
本共存,至少要
定义
multipart/alternative
段。
为什么说是
“至少”
?举个例子说,
如果只有纯文本与超文
本正文,那么在邮件头中将类型扩大化,定义为
multipart/related
,甚至
multipart/mixed
,
都是允许的。
p>
k-9-4.804srccomfsckk9mail
地址:
地址和通讯录名字之间的转换
身份认证:
函数作用:
计算对
CRAM-MD5<
/p>
认证机制的响应,
给用户提供认证信息和服务器提供随机数。
p>
package
import
eDigest;
import
64;
import
public
class
Authentication {
private
static
final
String
US_ASCII
=
;
/**
*
Computes the response for
CRAM
-
MD5 authentication
mechanism given the
user credentials
and
* the
server
-
provided
nonce.
*
*
@param
username The username.
*
@param
password The
password.
*
@param
b64Nonce The nonce as
base64
-
encoded
string.
*
@return
The
CRAM
-
MD5
response.
*
*
@throws
AuthenticationFailedException If something went
wrong.
*
*
@see
Authentication#computeCramMd5Bytes(String, String,
byte[])
*/
public
static
String
computeCramMd5(String username, String password,
String b64Nonce)
throws
AuthenticationFailedException {
try
{
byte
[] b64NonceBytes =
es(
US_ASCII
);
byte
[] b64CRAM =
computeCramMd5Bytes
(username, password,
b64NonceBytes);
return
new
String(b64CRAM,
US_ASCII
);
}
catch
(AuthenticationFailedException e) {
throw
e;
}
catch
(Exception e) {
throw
new
AuthenticationFailedExce
ption(
,
e);
}
}
/**
* Computes the response for
CRAM
-
MD5 authentication
mechanism given the
user credentials
and
* the
server
-
provided
nonce.
*
*
@param
username The username.
*
@param
password The
password.
*
@param
b64Nonce The nonce as
base64
-
encoded byte
array.
*
@return
The
CRAM
-
MD5 response as byte
array.
*
*
@throws
AuthenticationFailedException If something went
wrong.
*
*
@see
*/
public
static
byte
[]
computeCramMd5Bytes(String
username,
String
password,
byte
[]
b64Nonce)
throws
AuthenticationFailedException {
try
{
byte
[] nonce = Base64.
decodeBase64
(b64Nonce);
byte
[] secretBytes =
es(
US_ASCII
);
MessageDigest md = tance(
);
if
(secretBytes.
length
> 64) {
secretBytes =
(secretBytes);
}
byte
[] ipad =
new
byte
[64];
byte
[] opad =
new
byte
[64];
opy(secretBytes, 0, ipad, 0,
secretBytes.
length
);
opy(secretBytes, 0, opad,
0, secretBytes.
length
);
for
(
int
i = 0; i <
ipad.
length
; i++) ipad[i] ^=
0x36;
for
(
int
i = 0; i <
opad.
length
; i++) opad[i] ^=
0x5c;
(ipad);
byte
[] firstPass = (nonce);
(opad);
byte
[] result = (firstPass);
String
plainCRAM = username +
+
new
String(Hex.
p>
encodeHex
(result));
byte
[] b64CRAM =
Base64.
encodeBase64
(es(
US_ASCII
));
return
b64CRAM;
}
catch
(Exception e) {
throw
new
AuthenticationFailedExce
ption(
during CRAM-MD5
computation
, e);
}
}
}
ort;
k-9-4.804srccomfsckk9mailtransportimap
.k9
:
这是个实体类,也是
android
平台上
MVC
模式中的
Model
类,它除了封装
Email
账
户的信息外,还被设计用于保存账户的各种设置,包括账户身份认证设置
Identity
、字体设
置
p>
FontSizes
、通知设置
NotificationSetting
和邮件收发地址、
草稿箱、垃圾箱、总是密送到
的账户、
反垃圾用的文件夹、
p>
各种网络
(
3g
、
WiFi
等
)
连
接
下
是
否
启
用
压
缩
等
,
p>
这些数据使用
android
平台的
SharedPreferences
保存,
SharedPreferences
是平台下除了
SQLite
外另外一种方便好用的数据持久化方式,应该是
android
平台上最简单的读写外部
数据的方法,
特别适用于保存客户端不同用户的个性化设置信息。
< br>一个账户用一个
UUID
定
义,可以通过
mUuid
属性的值来区分两个账户。
Accou
类实现了接口
BaseAccoun
t
,这个
接口定义了获取、设置
Email
账户的及其描述的
String
类型的数据,还定义了获取账户
UUID
值的方法。通过
Account
可以获得账户对应的
LocalStore
实例,然后可以进一步获
得该账户在
SQLite
数据库里面保存的一切信息,包括邮件文件夹、
邮件等,还可以获得远
程邮件服务器的代理(
RemoteStore
,包括
ImapStore
、
Pop3Store
和
WebDav
Store
,这
些组件封装了对远程服务器的访问)
,并进一步获得其内部类(例如
ImapStore
的内部类
p>
ImapFolder
)
,实现对远程服务
器上相应对象的操作。
Account
的类型怎么区分的?通过
Account
类的属性
mStoreUri
,
不同类型的
Account
的
mStoreUri
的值以不同的前缀开头,
k9mail
分别使用
pop3
、
imap
和
webdav
表示相应的三种
Email
账户类型,该属性的值的
形式如下:
imap://PLAIN:
帐号
:<
/p>
密码
@:143/1%7C
这些数据变
化后,
k9mail
会调用
Accou
nt
类的
save
方法通过
把这
些数据保存到
xml
配置文件中。
该类存储了一个账号的所有信息。
Account stores all of the settings for
a single account defined by the user.
It
is
able
to
save
and
delete
itself
given
a
Preferences
to
work
with.
Each
account
is defined by a
UUID.
(
1
)
< br>Account
的默认信息:收发件箱、删除策略、网络类型、消息类型、键值、
颜色、排序类、
数据库
ID
等等
(
2
)
protected
Account(Context context)
设置账户的基本信息:
(
3
)
private
int
pickColor(Context
context)
* Pick a nice Android
guidelines color if we haven't used them all yet.
(
4
)
pro
tected
Account(Preferences
preferences, String uuid) {
this
.
mUuid
= uuid;
loadAccount(preferences);
}
(
5
)
private
synchronized void
loadAccount(Preferences preferences)
*
Load stored settings for this account.
(
6
)
protected
synchronized void
delete(Preferences preferences)
删除一个账户
(
7
)
public
static
int
findNewAccountNumber(List
为新账户建立一个
AccountNumber
(
8
)
public
static
List
preferences)
获得存在的所有帐户的
Account
Number
列表
(
9
)
public
static
int
generateAccountNumber(Preferences preferences)
生成一个
AccountNumber
(
10
)
public
void
move(Preferences
preferences,
boolean
moveUp)
移动账户的位置,上移或下移一位
(
11
)
public
< br>
synchronized
void
save(Preferences
preferences)
保存账户的配置信息。当账户被创建时,我们会为其分配一
个唯一的
Account Number
(
< br>12
)
public void
resetVisibleLimits()
重置可以显示的账户的个数
(
13
)
public
AccountStats getStats(Context context)
throws
MessagingException
获得帐户状态
(
14
)颜色相关的函数
public
synchronized
void
setChipColor(
int
color)
public
synchronized
void
cacheChips()
public
ColorChip getCheckmarkChip() {
return
mCheckmarkChip
;
}
public
synchronized
int
getChipColor() {
return
mChipColor
;
}
public
ColorChip
generateColorChip(
boolean
messageRead,
boolean
toMe,
boolean
ccMe,
boolean
fromMe,
boolean
messageFlagged)
public
ColorChip
generateColorChip() {
return
new
ColorChip(
mChipColor
,
false
,
ColorChip.
CIRCULAR
);
}
(
15
< br>)
public
String getUuid()
{
return
mUuid
;
}
获得当前账户的
Uuid
(
16
)
public<
/p>
Uri getContentUri() {
return
Uri.
parse<
/p>
(
+ getUuid());
}
获得当前账户的
ContentUri
(
16
)
public
synchronized
String
getStoreUri() {
return
mStoreUri
;
}
获得当前账户的
StoreUri
(
17
)
public
< br>
synchronized
void
setStoreUri(String
storeUri) {
this
.
mStoreUri
=
storeUri;
}
设置当前账户的
StoreUri
(
18
)
public
< br>
synchronized
String
getTransportUri() {
return
mTransportUri
;
}
获得当前账户的
TransportUri
(
19
)
public
p>
synchronized
void
setTransportUri(String
transportUri) {
this
.
mTransportUri
=
transportUri;
}
设置当前账户的
TransportUri
@Override
(
20
)
publi
c
synchronized
String getDescription() {
return
mDescription
;
}
@Override
(
21
)
public
synchronized
void
setDescription(String
description) {
this<
/p>
.
mDescription
=
description;
}
< br>(
22
)
public
synchronized
String
getName() {
return
identities
.get(0).getName();
}
(
22
)
public
synchronized
void
setName(String name) {
identities
.get(0).setName(name);
}
(
23
)<
/p>
public
synchronized
boolean
getSignatureUse() {
return
p>
identities
.get(0).getSignature
Use();
}
(
p>
24
)
public
synchronized
void
setSignatureUse(
boolean
signatureUse) {
iden
tities
.get(0).setSignatureUse(signature
Use);
}
(
25
)
public
synchronized
String
getSignature() {
return
identities
.get(0).getSignature();
}
(
26
)
public
synchronized
void
setSignature(String
signature) {
identit
ies
.get(0).setSignature(signature);
}
(
27
)
public
synchronized
String
getEmail() {
return
identities
.get(0).getEmail();
}
p>
(
28
)
publ
ic
synchronized
void
setEmail(String email)
{
identities
< br>.get(0).setEmail(email);
}
(
29
)<
/p>
public
synchronized
String
getAlwaysBcc() {
return
mAlwaysBcc
;
}
(
30
)<
/p>
public
synchronized
void
setAlwaysBcc(String
alwaysBcc) {
this
.
mAlwaysBcc
=
alwaysBcc;
}
/* Have we sent a new
mail notification on this account */
p>
(
31
)
publ
ic
boolean
isRingNotified() {
return
mRingNotified
;
}
(
32
)
public
void
setRingNotified(
boolean
ringNotified) {
mRingNotified
=
ringNotified;
}
(
33
)
public
String getLocalStorageProviderId() {
return
mLocalStorageProviderId
;
}
(
34
)
public
void
setLocalStorageProviderId(String id)
(
35
)
public
< br>
synchronized
int
getAutomaticCheckIntervalMinutes() {
return
mAutomatic
CheckIntervalMinutes
;
}
* Returns
-
1
for never.
(
36
)
public
synchronized
boolean
setAutomaticCheckInt
ervalMinutes(
int
automaticCheckIntervalMinutes)
*
@param
automaticCheckIntervalMinutes or
-
1 for never.
(
37
)
pu
blic
synchronized
int
getDisplayCount()
return
mDisplayCount
;
}
(
38
)
public
synchronized
void
setDisplayCount(
int
displayCount) {
if
(displayCount != -1) {
this
.
mDisplayCount
=
displayCount;
}
else
{
this
.
mDisplayCoun
t
=
K9.
DEFAULT_VISIBLE_LIMIT
;
}
resetVisibleLimits();
}
(
39
)
pu
blic
synchronized
long
getLastAutomaticCheckTime() {
return
mLastAutomaticCheckTime
;
}
-
-
-
-
-
-
-
-
-
上一篇:【有机化学专业英语词汇】
下一篇:sendmail邮件服务器详细配置讲解