本文实现了在好友生日前自动发送提醒邮件的功能。
android.util.Patterns自带的正则表达式实现邮箱验证。Calender获取日历。DatePickerDialog实现选择日期。AlarmManager定时器实现系统后台提醒功能。Java mail系统自动发送邮件,使用Java mail发送文件需要网络权限。邮件,生日用SharedPreference保存。所有代码如下。
github https://github.com/tashaerxing/SendMail
* AlarmManager定时器 四步 * AlarmManager是Android中的一种系统级别的提醒服务,它会为我们在特定的时刻广播一个指定的Intent。 * 相对时间:SystemClock.elapsedRealtime(); * 绝对时间:System.currentTimeMillis(); * 1.实例化 AlarmManager。 * AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE); * 2.确认意图。Intent intent = new Intent(this,SendEmailIntentService.class); * 3.延迟意图,get方法。PendingIntent pi = PendingIntent.getService(this,0,intent,0); * 4.设置周期。set方法。//定时器:四个参数(绝对时间,当前系统时间,每天INTERVAL_DAY,pendingIntent) * alarmManager.setRepeating(AlarmManager.RTC,System.currentTimeMillis(), * AlarmManager.INTERVAL_DAY,pi);
package com.example.sendemail; import android.Manifest; import android.app.DatePickerDialog; import java.util.Calendar; import android.app.PendingIntent; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.RadioButton; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.DatePicker; import android.widget.EditText; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; import android.util.Patterns; import android.app.AlarmManager; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private EditText mail; private TextView date; private Button ack; private int preyear;//初始化的年月日 private int premonth; private int preday; private int themeResId;//日历格式 private SharedPreferences sharedPreferences; private SharedPreferences.Editor editor; private AlarmManager alarmManager; private RadioGroup radioGroup; private boolean send;//判断是否开启生日提醒 private RadioButton yesSend; private RadioButton noSend; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // requestWindowFeature(Window.FEATURE_NO_TITLE);加了这句话后程序崩溃,未解决日历样式 init(); date.setOnClickListener(this); ack.setOnClickListener(this); radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId){ case R.id.yesSend: editor.putBoolean("send",true); editor.apply(); //发送邮件需要获取网络权限 if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission. INTERNET)!= PackageManager.PERMISSION_GRANTED){ //如果没有权限,向用户申请权限 ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest .permission.INTERNET},1); }else { StartEmailService(); } break; case R.id.noSend: editor.putBoolean("send",false); editor.apply(); //如果开启生日提醒,在这里关闭生日提醒 CancelEmailService(); break; default:break; } } }); } private void init(){ mail = (EditText)findViewById(R.id.mail); date = (TextView) findViewById(R.id.date); ack = (Button)findViewById(R.id.ack); radioGroup = (RadioGroup)findViewById(R.id.pickMail); yesSend = (RadioButton)findViewById(R.id.yesSend); noSend = (RadioButton)findViewById(R.id.noSend); //获取系统时间 Calendar calendar = Calendar.getInstance(); //从sheredPerference中获取数据,没有数据显示当前时间 sharedPreferences = getSharedPreferences("data",0); editor = sharedPreferences.edit(); //初始化日期和邮箱 preyear = sharedPreferences.getInt("year",calendar.get(Calendar.YEAR)); premonth = sharedPreferences.getInt("month",calendar.get(Calendar.MONTH)+1); preday = sharedPreferences.getInt("day",calendar.get(Calendar.DAY_OF_MONTH)); String Email = sharedPreferences.getString("email",null);//邮箱值 send = sharedPreferences.getBoolean("send",false); date.setText(preyear+"年"+premonth +"月"+ preday+"日"); mail.setText(Email); if(send){ // radioGroup.check(yesSend.getId()); yesSend.setChecked(true); }else { // radioGroup.check(noSend.getId()); noSend.setChecked(true); } // Log.d("send 的值",String.valueOf(send)); // themeResId = DatePickerDialog.THEME_HOLO_LIGHT; themeResId = 3; } public void StartEmailService(){ //如果选中生日邮箱提醒,开启周期性系统服务 alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE); Intent intent = new Intent(MainActivity.this,SendEmailIntentService.class); PendingIntent pi = PendingIntent.getService(MainActivity.this,0,intent,0); //定时器:四个参数(绝对时间,当前系统时间,每天INTERVAL_DAY,pendingIntent) alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), AlarmManager.INTERVAL_DAY,pi); } public void CancelEmailService(){ alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE); Intent intent = new Intent(MainActivity.this,SendEmailIntentService.class); PendingIntent pi = PendingIntent.getService(MainActivity.this,0,intent,0); //定时器:四个参数(绝对时间,当前系统时间,每天INTERVAL_DAY,pendingIntent) alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), AlarmManager.INTERVAL_DAY,pi); if(pi!=null){ alarmManager.cancel(pi); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode){ case 1: if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){ //如果有网络,可以发送邮件 StartEmailService(); }else { //没有网络 Toast.makeText(this,"邮箱提醒开启失败,请开启网络权限",Toast.LENGTH_LONG).show(); noSend.setChecked(true); } } } @Override public void onClick(View v) { switch (v.getId()){ case R.id.date: new DatePickerDialog(MainActivity.this, themeResId,new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { //日期改变后,用sheredperfreference保存 month++; preyear = year; premonth = month; preday = dayOfMonth; editor.putInt("year",year); editor.putInt("month",month); editor.putInt("day",dayOfMonth); editor.apply(); date.setText(year+"年"+month +"月"+ dayOfMonth+"日"); } },preyear,premonth-1,preday).show(); case R.id.ack://在这里判断邮箱是否正确 //首先获取输入的邮箱 String email = mail.getText().toString(); if("".equals(email)){ //email == null这里==并没有起作用,==比较的是两个对象的地址,equals比较的是两个对象的内容 //如果邮箱为空 Toast.makeText(MainActivity.this,"请输入邮箱"+email,Toast.LENGTH_SHORT).show(); }else { //如果邮箱不为空,判断邮箱格式是否正确 if(!isEmail(email)){ //如果邮箱格式不正确 Toast.makeText(MainActivity.this,"请输入正确的邮箱地址",Toast.LENGTH_SHORT).show(); }else { //将真确的邮箱保存 editor.putString("email",email); editor.apply(); Toast.makeText((MainActivity.this),"邮箱地址正确",Toast.LENGTH_SHORT).show(); //邮箱地址正确,记录下邮箱,和生日,在生日前三天发送邮件提醒。 } } default:break; } } public boolean isEmail(String email){ //邮箱的正则表达式 return Patterns.EMAIL_ADDRESS.matcher(email).matches(); } }
Intent不能实现后台自动发送邮件的功能,改为Java mail
* javamail实现发送邮件,首先需要依赖additional.jar、mail.jar和activation.jar这3个jar包。
* Properties 属性文件以 key value 存储值
* Authenticator访问受保护的服务器资源
* Session 客户端与服务器端的会话。Session对象需要知道用来处理邮件的SMTP服务器。
* MimeMessage 存储我们实际发送的电子邮件信息,
* InternetAddress 源地址和目标地址
* Transport 发送信息
链接失败:
properties.setProperty("mail.smtp.starttls.enable","true");//错误530。要打开tls安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。
package com.example.sendemail; import android.app.IntentService; import android.content.Intent; import android.content.Context; import android.content.SharedPreferences; import java.util.Calendar; import java.text.SimpleDateFormat; import javax.mail.MessagingException; /** * An {@link IntentService} subclass for handling asynchronous task requests in * a service on a separate handler thread. * <p> * TODO: Customize class - update intent actions, extra parameters and static * helper methods. */ public class SendEmailIntentService extends IntentService { // TODO: Rename actions, choose action names that describe tasks that this // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS private static final String ACTION_FOO = "com.example.sendemail.action.FOO"; private static final String ACTION_BAZ = "com.example.sendemail.action.BAZ"; // TODO: Rename parameters private static final String EXTRA_PARAM1 = "com.example.sendemail.extra.PARAM1"; private static final String EXTRA_PARAM2 = "com.example.sendemail.extra.PARAM2"; public SendEmailIntentService() { super("SendEmailIntentService"); } /** * Starts this service to perform action Foo with the given parameters. If * the service is already performing a task this action will be queued. * * @see IntentService */ // TODO: Customize helper method public static void startActionFoo(Context context, String param1, String param2) { Intent intent = new Intent(context, SendEmailIntentService.class); intent.setAction(ACTION_FOO); intent.putExtra(EXTRA_PARAM1, param1); intent.putExtra(EXTRA_PARAM2, param2); context.startService(intent); } /** * Starts this service to perform action Baz with the given parameters. If * the service is already performing a task this action will be queued. * * @see IntentService */ // TODO: Customize helper method public static void startActionBaz(Context context, String param1, String param2) { Intent intent = new Intent(context, SendEmailIntentService.class); intent.setAction(ACTION_BAZ); intent.putExtra(EXTRA_PARAM1, param1); intent.putExtra(EXTRA_PARAM2, param2); context.startService(intent); } @Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_FOO.equals(action)) { final String param1 = intent.getStringExtra(EXTRA_PARAM1); final String param2 = intent.getStringExtra(EXTRA_PARAM2); handleActionFoo(param1, param2); } else if (ACTION_BAZ.equals(action)) { final String param1 = intent.getStringExtra(EXTRA_PARAM1); final String param2 = intent.getStringExtra(EXTRA_PARAM2); handleActionBaz(param1, param2); } } // Log.d("SendEmailIntentService","在这里发送邮件"); SharedPreferences preferences = getSharedPreferences("data",0); String email = preferences.getString("email",null); if(!"".equals(email) && email!=null) { // //如果邮箱不为空,发送提醒邮件 //使用intent发送邮件,不能自动发送 // Intent sendEmail = new Intent(Intent.ACTION_SENDTO);//纯文本,不用附件 // sendEmail.setData(Uri.parse("mailto:"+email));//目标地址 // sendEmail.putExtra(Intent.EXTRA_SUBJECT,"生日提醒");//设置标题 // sendEmail.putExtra(Intent.EXTRA_TEXT,"又有人过生日啦,礼物买好了吗?");//内容 // startActivity(sendEmail); try { //判断日期,在生日前三天发送邮件 SimpleDateFormat format = new SimpleDateFormat("MM-dd"); //内存中的生日 Calendar calendar1 = Calendar.getInstance(); int biryear = preferences.getInt("year",0); int birmonth = preferences.getInt("month",0)-1; int birday = preferences.getInt("day",0); calendar1.set(biryear,birmonth,birday); String date1 = format.format(calendar1.getTime()); // Log.d("data1",date1); //当前日期的三天前 Calendar calendar2 = Calendar.getInstance(); calendar2.set(Calendar.DATE,calendar2.get(Calendar.DATE)-3); String date2 = format.format(calendar2.getTime()); // Log.d("date2",date2); if(date1.equals(date2)){ new SendMail(email).send(); } //使用Javamail发送邮件,能自动发送 }catch (MessagingException e){ e.printStackTrace(); } }else { // Toast.makeText(this,"请输入邮箱地址",Toast.LENGTH_SHORT); stopSelf(); } } /** * Handle action Foo in the provided background thread with the provided * parameters. */ private void handleActionFoo(String param1, String param2) { // TODO: Handle action Foo throw new UnsupportedOperationException("Not yet implemented"); } /** * Handle action Baz in the provided background thread with the provided * parameters. */ private void handleActionBaz(String param1, String param2) { // TODO: Handle action Baz throw new UnsupportedOperationException("Not yet implemented"); } }
package com.example.sendemail; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; public class SendMail { private String target; public SendMail(String target){ //目标邮箱地址 this.target = target; } public void send()throws AddressException,MessagingException { Properties properties = new Properties(); //设置验证setProperty的参数只能是String,更安全 properties.setProperty("mail.smtp.host","smtp.qq.com"); properties.setProperty("mail.smtp.auth","true"); properties.setProperty("mail.smtp.starttls.enable","true");//错误530 // properties.setProperty("mail,smtp.port","465"); //访问受保护的服务器资源 MyAuthenticator authenticator = new MyAuthenticator("851059665","itochdvtspfmbcca"); //Session 客户端与服务器端的会话.Session对象需要知道用来处理邮件的SMTP服务器。 Session session = Session.getInstance(properties,authenticator); // session.setDebug(true);//代表启用debug模式,可以在控制台输出smtp协议应答的过程 // Message对象将存储我们实际发送的电子邮件信息, // Message需要知道应当选择哪一个JavaMail session。 MimeMessage message = new MimeMessage(session); //源地址和目标地址 InternetAddress soureceAddress = new InternetAddress("851059665@qq.com"); InternetAddress targetAddress = new InternetAddress(target); //设置要发送的邮件信息 message.setFrom(soureceAddress); message.addRecipient(Message.RecipientType.TO,targetAddress); message.setSubject("生日提醒"); message.setText("又有人过生日啦,礼物准备好了吗?"); message.saveChanges(); //设置发送协议 Transport transport = session.getTransport("smtp"); transport.connect("smtp.qq.com","851059665@qq.com","itochdvtspfmbcca"); transport.sendMessage(message,message.getAllRecipients()); transport.close(); } }
package com.example.sendemail; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; /** * Created by lenovo on 2018/5/28. */ public class MyAuthenticator extends Authenticator { String userName = null; String password = null; public MyAuthenticator(String userName,String password){ this.userName = userName; this.password = password; } public MyAuthenticator() { super(); } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName,password); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.sendemail.MainActivity"> <TextView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" android:gravity="center_vertical|left" android:textSize="18sp" android:text="请输入正确的邮箱地址" /> <EditText android:id="@+id/mail" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" android:textSize="18sp" android:lines="1" android:inputType="textEmailAddress" android:gravity="center_vertical|left" /> <TextView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" android:textSize="18sp" android:gravity="center_vertical|left" android:text="请输入好友生日"/> <TextView android:id="@+id/date" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" android:gravity="center_vertical|left" android:clickable="true" android:textSize="18sp" /> <Button android:id="@+id/ack" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" android:textSize="18sp" android:gravity="center" android:text="确定"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="0dp" android:orientation="horizontal" android:textSize="18sp" android:gravity="center_vertical|left" android:layout_weight="2"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:gravity="center_vertical|left" android:text="是否开启生日提醒"/> <RadioGroup android:id="@+id/pickMail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioButton android:id="@+id/yesSend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:gravity="center_vertical|left" android:text="是" /> <RadioButton android:id="@+id/noSend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:gravity="center_vertical|left" android:text="否" android:checked="true" /> </RadioGroup> </LinearLayout> </LinearLayout>
529

被折叠的 条评论
为什么被折叠?



