写点什么

Android 进阶 (一)Android 发邮件与几种网络请求方式详解

  • 2022 年 8 月 11 日
    江苏
  • 本文字数:5391 字

    阅读完需:约 18 分钟

Android进阶(一)Android 发邮件与几种网络请求方式详解

一、邮件发送​

最近在做的 APP 涉及到发邮件,总结如下:

在 android 里进行邮件客户端开发可以有两种方式:在邮件客户端的设计中,可以采用两种方法。

一种是调用 android 系统自带的邮件服务

  • 优点:这种方法比较简单易用

  • 缺点:发送邮件的账号必须是 gmail 账号

令一种方法是采用 javamail 功能包

  • 优点:可以设置邮件服务器地址,不必局限于 gmail 邮箱

  • 缺点:用法比较复杂

下面依次介绍这两种方式:

先看应用 android 自带邮件系统的关键代码

     

//建立Intent对象  
Intent intent = new Intent();  
//设置对象动作  
intent.setAction(Intent.ACTION_SEND);  
//设置对方邮件地址  
intent.putExtra(Intent.EXTRA_EMAIL, new String[]    
{ "abc@com.cn","edf@com.cn" });   
//设置标题内容  
intent.putExtra(Intent.EXTRA_SUBJECT, "test");  
//设置邮件文本内容  
intent.putExtra(Intent.EXTRA_TEXT, "test mail");  
//启动一个新的ACTIVITY,"Sending mail..."是在启动这个ACTIVITY的等待时间时所显示的文字  
startActivity(Intent.createChooser(intent, "Sending    
mail..."));     
复制代码


只有上面的代码有可能还会出现异常,你运行的时候会提示一个错误:no application can perform this action 会有这个错误提示,是由于你没有在模拟器上配置 gmail 邮箱,输入自己的 gmail 账号和密码,默认使用的是你的 gmail 账号发信。


二、使用 javamail 实现的代码

在 android 里使用 javamail 需要依赖 3 个包,activation.jar,additionnal.jar,mail.jar,在编程中发现,其实 additionnal.jar 存在与否不影响结果。

同时还要注意一个最重要的地方那就是开启你访问互联网的权限不然你一点用没有。


 <uses-permission android:name="android.permission.INTERNET"></uses-permission>  
复制代码


对于 JavaMail,最基础的功能就是邮件的发送和接收,在这里,先讲一讲邮件的发送。


在写具体的程序前,先讲一些概念。1.邮件的发送:如果你的邮件地址是 a@host.com,而你要用这个邮箱发送一封邮件到 to@tohost.com,这个发送过程是怎样的呢,你以为是先连接到 tohost.com 这服务器上,然后把邮件发送出去吗?其实不然。最初,你需要连接到服务器 host.com 上,当然这个连接可能需要认证,然后是发送邮件到服务器 host.com 上,关闭连接。在 host.com 上,你所发送的邮件进入发送队列中,轮到你要发送的邮件时,host.com 主机再联系 tohost.com,将邮件传输到服务器 tohost.com 上。2.一些垃圾邮件的发送:在垃圾邮件中,可能大部分的发件人的地址都是假的,这是怎么回事呢?实际上在发送这些垃圾邮件的时候,这里的 host.com 有些特别,可能 host.com 不需要对用户进行认证,也可能发送垃圾邮件的人本来就控制着服务器 host.com,然后控制着 host.com 向其他服务器,如 tohost.com,发送邮件,而发送邮件的内容可以被控制,发件人的地址就可以随便填写。


发送邮件主要包括 3 个部分:创建连接,创建邮件体,发送邮件


JavaMail 中,是使用会话(Session)来管理连接的。创建一个连接,就需要创建一个会话。在会话中,有两个重要的因素,一是会话的属性,二是会话的认证。在我们使用 Hotmail 等邮件工具的时候,就要设置”SMTP 服务器身份验证”,也就是这里的会话的认证。


//首先,创建一个连接属性
Properties props = new Properties();
//设置smtp的服务器地址是smtp.126.com
props.put("mail.smtp.host","smtp.126.com");  
//设置smtp服务器要身份验证
props.put("mail.smtp.auth","true");          
PopupAuthenticator auth = new PopupAuthenticator();
// 创建会话(JavaMail中,是使用会话(Session)来管理连接的)
Session session = Session.getInstance(prop, auth);
// 创建邮件体
Message message = createmessage(session, user);
// 发送邮件-创建连接
Transport ts = null;
// 校验客服邮箱
try {
session.setDebug(true);
ts = session.getTransport("smtp");
// 此处的邮件发送方邮箱密码可知无可厚非
ts.connect(ConstantValue.MAILHOST, ConstantValue.MAILADDRESS,
ConstantValue.MAILPWD);
flag = true;
} catch (AuthenticationFailedException ae) {
ae.printStackTrace();
flag = false;
System.out.println("客服邮箱名或密码错误,请重新输入");
return SUCCESS;
} catch (MessagingException mex) {
mex.printStackTrace();
Exception ex = null;
if ((ex = mex.getNextException()) != null) {
ex.printStackTrace();
}
flag = false;
System.out.println("客服邮箱名或密码错误,请重新输入");
return SUCCESS;
}
ts.send(message);
ts.close();
}
复制代码


其中涉及到创建一个身份验证。身份验证稍微复杂一点,要创建一个 Authenticator 的子类,并重载 getPasswordAuthentication()方法,代码如下:

public class PopupAuthenticator extends Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
String username = ConstantValue.MAILADDRESS;
String pwd = ConstantValue.MAILPWD;
return new PasswordAuthentication(username, pwd);
}
}
复制代码


其中的类 ConstantValue 如下:

public class ConstantValue {
//邮件服务器
public static String MAILSENDER = "*秋亚";
//邮件服务器
public static String MAILHOST = "smtp.163.com";
//发送邮件地址
public static String MAILADDRESS = "sunhuaqiang2014";
//发送邮件密码
public static String MAILPWD = "35****";
}
复制代码

其中涉及到的 createmessage()方法如下:

public Message createmessage(Session session, User user)
throws AddressException, MessagingException, UnsupportedEncodingException {
MimeMessage message = new MimeMessage(session);
//发送人地址
message.setFrom(new InternetAddress(ConstantValue.MAILADDRESS + "@163.com", ConstantValue.MAILSENDER));
//收件人地址
message.setRecipient(Message.RecipientType.TO,
new InternetAddress(user.getEmail()));
//设置邮件主题
message.setSubject("彩票网密码找回");
//设置邮件内容
String content = "恭喜您密码成功找回 您注册的用户名:" + user.getUsername() + ",您注册的密码是:"
+ user.getPassword() + ",请妥善保管!!";
message.setContent(content, "text/html;charset=UTF-8");
message.saveChanges();
return message;
}
复制代码

三、拓展阅读

Android应用经常会和服务器端交互,这就需要手机客户端发送网络请求,下面介绍四种常用网络请求方式。

3.1 Get 方式

// Get方式请求
public static void requestByGet() throws Exception {
    String path = "https://reg.163.com/logins.jsp?id=helloworld&pwd=android";
    // 新建一个URL对象
    URL url = new URL(path);  
    // 打开一个HttpURLConnection连接
    HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
    // 设置连接超时时间
    urlConn.setConnectTimeout(5 * 1000);
    // 开始连接
    urlConn.connect();
    // 判断请求是否成功
    if (urlConn.getResponseCode() == HTTP_200) {
        // 获取返回的数据
        byte[] data = readStream(urlConn.getInputStream());  
        Log.i(TAG_GET, "Get方式请求成功,返回数据如下:");  
        Log.i(TAG_GET, new String(data, "UTF-8"));  
    } else {
        Log.i(TAG_GET, "Get方式请求失败");
    }
    // 关闭连接
    urlConn.disconnect();
}
复制代码


3.2 Post 方式

// Post方式请求  
public static void requestByPost() throws Throwable {  
    String path = "https://reg.163.com/logins.jsp";  
    // 请求的参数转换为byte数组  
    String params = "id=" + URLEncoder.encode("helloworld", "UTF-8")  
            + "&pwd=" + URLEncoder.encode("android", "UTF-8");  
    byte[] postData = params.getBytes();  
    // 新建一个URL对象  
    URL url = new URL(path);  
    // 打开一个HttpURLConnection连接  
    HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();  
    // 设置连接超时时间  
    urlConn.setConnectTimeout(5 * 1000);  
    // Post请求必须设置允许输出  
    urlConn.setDoOutput(true);  
    // Post请求不能使用缓存  
    urlConn.setUseCaches(false);  
    // 设置为Post请求  
    urlConn.setRequestMethod("POST");  
    urlConn.setInstanceFollowRedirects(true);  
    // 配置请求Content-Type  
    urlConn.setRequestProperty("Content-Type",  
            "application/x-www-form-urlencode");  
    // 开始连接  
    urlConn.connect();  
    // 发送请求参数  
    DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());  
    dos.write(postData);
    dos.flush();
    dos.close();
    // 判断请求是否成功
    if (urlConn.getResponseCode() == HTTP_200) {
        // 获取返回的数据
        byte[] data = readStream(urlConn.getInputStream());
        Log.i(TAG_POST, "Post请求方式成功,返回数据如下:");
        Log.i(TAG_POST, new String(data, "UTF-8"));
    } else {
        Log.i(TAG_POST, "Post方式请求失败");
    }
}
复制代码


org.apache.http 包中的 HttpGet 和 HttpPost 类


Get 方式:

// HttpGet方式请求  
public static void requestByHttpGet() throws Exception {  
    String path = "https://reg.163.com/logins.jsp?id=helloworld&pwd=android";  
    // 新建HttpGet对象  
    HttpGet httpGet = new HttpGet(path);  
    // 获取HttpClient对象  
    HttpClient httpClient = new DefaultHttpClient();  
    // 获取HttpResponse实例  
    HttpResponse httpResp = httpClient.execute(httpGet);  
    // 判断是够请求成功  
    if (httpResp.getStatusLine().getStatusCode() == HTTP_200) {  
        // 获取返回的数据  
        String result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");  
        Log.i(TAG_HTTPGET, "HttpGet方式请求成功,返回数据如下:");  
        Log.i(TAG_HTTPGET, result);  
    } else {  
        Log.i(TAG_HTTPGET, "HttpGet方式请求失败");
    }
}  
复制代码


Post 方式:

// HttpPost方式请求  
public static void requestByHttpPost() throws Exception {  
    String path = "https://reg.163.com/logins.jsp";  
    // 新建HttpPost对象  
    HttpPost httpPost = new HttpPost(path);  
    // Post参数  
    List<NameValuePair> params = new ArrayList<NameValuePair>();  
    params.add(new BasicNameValuePair("id", "helloworld"));  
    params.add(new BasicNameValuePair("pwd", "android"));  
    // 设置字符集
    HttpEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
    // 设置参数实体
    httpPost.setEntity(entity);
    // 获取HttpClient对象
    HttpClient httpClient = new DefaultHttpClient();
    // 获取HttpResponse实例
    HttpResponse httpResp = httpClient.execute(httpPost);
    // 判断是够请求成功
    if (httpResp.getStatusLine().getStatusCode() == HTTP_200) {
        // 获取返回的数据
        String result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
        Log.i(TAG_HTTPGET, "HttpPost方式请求成功,返回数据如下:");
        Log.i(TAG_HTTPGET, result);
    } else {
        Log.i(TAG_HTTPGET, "HttpPost方式请求失败");
    }
}
复制代码


以上是一些部分代码,测试的时候在测试类中运行对应的测试方法即可。

发布于: 刚刚阅读数: 5
用户头像

No Silver Bullet 2021.07.09 加入

岂曰无衣 与子同袍

评论

发布
暂无评论
Android进阶(一)Android 发邮件与几种网络请求方式详解_android_No Silver Bullet_InfoQ写作社区