最近Android软件程序要添加意见反馈功能,我想三个方案:
使用调用手机上的其他程序完成邮件发送,但是如果用户手机上没有邮箱客户端就坑爹了,并且影响程序的美观,放弃这个方案。
使用javamail完成邮件发送
利用我现有sae建立一个邮箱转发服务器,可是我对php语言不熟,实现起来比较麻烦。
综上决定采用第二种方案
直接在网上撸了段代码拿来用,结果发送不成功,我想是不是邮箱配置错了,下了个foxmail,根据foxmail的邮件配置,重新填了一下,还是没法发送。
后来想到是不是Androidmainfest没配置权限,配置好了,代码也对,还是发送不了,一点击button就提示system.err at onclick(),就是说onclick事件错误,后来突然发现从2.3开始,联网的Android程序需要用StrictMode,于是添加StrictMode,运行ok,邮件发送成功。
javamail使用详细过程如下:
去http://code.google.com/p/javamail-android/,下载additionnal.jar、mail.jar、activation.jar 三个包,,把那三个jar包都添加到程序。
添加Androidmainfest权限
新建一个MailUtil工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package
com.bqkj.co2.util;
import
java.util.Properties;
import
javax.mail.Message;
import
javax.mail.MessagingException;
import
javax.mail.Session;
import
javax.mail.Transport;
import
javax.mail.internet.InternetAddress;
import
javax.mail.internet.MimeMessage;
/**
*
* @author alan wang
*
*/
public
class
MailUtil {
public
static
void
snedMail(String subject, String content)
throws
MessagingException {
// Properties props = new Properties();
// props.setProperty("mail.transport.protocol", "smtp");
// props.setProperty("mail.host", "smtp.sina.com");
// props.put("mail.smtp.auth", "true");
// props.put("mail.smtp.port", "465");
// props.put("mail.smtp.socketFactory.port", "465");
// props.put("mail.smtp.socketFactory.class",
// "javax.net.ssl.SSLSocketFactory");
// props.put("mail.smtp.socketFactory.fallback", "false");
// props.setProperty("mail.smtp.quitwait", "false");
Properties props =
new
Properties();
props.put(
"mail.smtp.host"
,
"mail.sina.cn"
);
// 存储发送邮件服务器的信息
props.put(
"mail.smtp.auth"
,
"true"
);
// 同时通过验证
// 创建邮件会话
Session session = Session.getInstance(props);
//session.setDebug(true);
// 邮件体
MimeMessage message =
new
MimeMessage(session);
// 发邮件
InternetAddress fromAddress =
null
;
fromAddress =
new
InternetAddress(
"发送邮箱@sina.com"
);
message.setFrom(fromAddress);
// 收件地址
InternetAddress toAddress =
new
InternetAddress(
"接收@qq.com"
);
message.addRecipient(Message.RecipientType.TO, toAddress);
// 解析邮件内容
message.setSubject(subject);
// 设置信件的标题
message.setText(content);
// 设置信件内容
message.saveChanges();
//存储信息
// send message
Transport transport =
null
;
transport = session.getTransport(
"smtp"
);
transport.connect(
"smtp.sina.com"
,
"发送邮箱@sina.com"
,
"密码"
);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
}
|
4.发送邮件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
@Override
protected
void
onCreate(Bundle savedInstanceState) {
//联网程序,需要加上StrictMode
StrictMode.setThreadPolicy(
new
StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
StrictMode.setVmPolicy(
new
StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
.penaltyLog().penaltyDeath().build());
super
.onCreate(savedInstanceState);
setContentView(R.layout.post_email);
// context=this.getApplicationContext();
Button btn_send = (Button) findViewById(R.id.send_mail);
// EditText contens = (EditText) findViewById(R.id.ed_contents);
// EditText phone = (EditText) findViewById(R.id.ed_phone);
// txt_conts = contens.getText().toString();
// txt2_phone = phone.getText().toString();
btn_send.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// if (!txt2_phone.equals("") && !txt_conts.equals("")) {
// try {
try
{
MailUtil.snedMail(
"新风Android软件意见反馈"
,
"test"
);
Toast.makeText(SendMailActivity.
this
,
"send ok"
,
Toast.LENGTH_LONG).show();
}
catch
(MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Util.showTost(context, "反馈意见成功!感谢您!.", Toast.LENGTH_LONG);
// Log.i("发送成功", "t");
// Intent intent=new Intent(SendMailActivity.this,
// MainActivity.class);
// intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// startActivity(intent);
// } catch (MessagingException e) {
// // TODO Auto-generated catch block
// Util.showTost(context, "发送失败:"+e.getMessage(),
// Toast.LENGTH_LONG);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// Util.showTost(context, "发送失败:"+e.getMessage(),
// Toast.LENGTH_LONG);
// }
// } else {
// Util.showTost(context, "请输入您建议和联系方式...", Toast.LENGTH_LONG);
// }
}
});
}
|
现在可以发送邮件了、
那么strickmode到底干什么用的?
http://developer.android.com/reference/android/os/StrictMode.html
由此可知主要用于,当使用磁盘和网络连接的时候,会帮助程序员发现潜在的错误
如果在主线程中访问网络或者读写磁盘或者数据库的读写等做一些很耗时的操作,logcat将会输出错误信息
如:
通过分析logcat信息,我们可以找出程序潜在的界面无响应,进一步优化代码。
推荐的使用StrictMode的方式是,在开发阶段,打开它,在发布应用前,关闭它。
所以经过上述,源程序做了如下更改
package com.bqkj.amesdial;
import javax.mail.MessagingException;
import com.bqkj.amesdial.util.DialogFactory;
import com.bqkj.amesdial.util.MailUtil;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
public class SendMailActivity extends Activity {
private String txt_conts = null;
private String txt2_phone = null;
private Context context = null;
private EditText contens = null;
private EditText email = null;
private Dialog mDialog = null;
private void showRequestDialog() {
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
}
mDialog = DialogFactory.creatRequestDialog(this, "发送邮件中...");
mDialog.setCanceledOnTouchOutside(false);
mDialog.show();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// 联网程序,需要加上StrictMode
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
.penaltyLog().penaltyDeath().build());
super.onCreate(savedInstanceState);
setContentView(R.layout.post_email);
context = this.getApplicationContext();
contens = (EditText) findViewById(R.id.ed_contents);
email = (EditText) findViewById(R.id.ed_emial);
ActionBar bar = getActionBar(); // 获取ActionBar的对象,从这个方法也可知action
// bar是activity的一个属性
bar.setDisplayHomeAsUpEnabled(true); // 显示返回的箭头,并可通过onOptionsItemSelected()进行监听,其资源ID为android.R.id.home。
// txt_conts = contens.getText().toString();
// txt2_phone = email.getText().toString();这样肯定获取不到EditText的内容
email.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// showRequestDialog();
txt_conts = contens.getText().toString().trim();
txt2_phone = email.getText().toString().trim();
int txt_conts1 = txt_conts.length();
int txt2_phone2 = txt2_phone.length();
if (txt_conts1 >= 1 && txt2_phone2 >= 1) {
showRequestDialog();
new Thread() {
public void run() {
try {
MailUtil.snedMail("新风Android软件意见反馈",
txt_conts + "\n"
+ "---------------------"
+ "\n" + txt2_phone);
myHandler.sendEmptyMessage(2);
} catch (MessagingException e) {
// TODO Auto-generated catch block
myHandler.sendEmptyMessage(1);
}
}
}.start();
} else {
myHandler.sendEmptyMessage(3);
}
}
return false;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: // 对用户按home
// icon的处理,本例只需关闭activity,就可返回上一activity,即主activity。
Intent i = new Intent(this, AboutActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);// 清空原来的MainActivity,重新建一个,如果有蓝牙连接的话,就会断开,请注意!!
startActivity(i);
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
String messs = "";
switch (msg.what) {
case 1:
messs = "发送失败!";
mDialog.dismiss();
Thread.currentThread().interrupt();
break;
case 2:
messs = "发送成功!";
mDialog.dismiss();
Thread.currentThread().interrupt();
break;
case 3:
messs = "发送内容不能为空!";
break;
default:
break;
}
Toast.makeText(context, messs, Toast.LENGTH_LONG).show();
}
};
}