こんにちはandroidでアプリ開発を学習中のみのむしと申します。
今回は、Javamailを勉強したため応用してお問い合わせフォームっぽいのを作ってみました。
仕組みとしては、送信元アドレスと送信先アドレスを設定し、
一度メールを送信したら以降はメールの本文の中に記載したユーザーのアドレス
と送信先アドレス間でやり取りを行うイメージです。
gmailの設定等
今回はSMTP通信を使って実装していきます。
また、以前までは、gmail内にある「セキュリティ > 安全性の低いアプリのアクセス」を有効にする設定を行うことでSMTP通信が可能でしたが、2022年5月30日より、ユーザー名とパスワードのみでGoogleアカウントにログインするサードパーティ製のアプリとデバイスについてサポートが終了してしまったため、こちらの方法が使えなくなってしまいました。
そのため、今回は以下のサイトを参考にしながらアプリパスワードを発行し、SMTP通信を許可していきます。
https://itblogdsi.blog.fc2.com/blog-entry-470.html
gradleにJavaMailが使えるように必要な記述を行う
Appのbuild.gradleに下記を加えるpackagingOptions {
exclude 'META-INF/NOTICE.md'
exclude 'META-INF/LICENSE.md'
}
dependencies {
implementation 'com.sun.mail:android-mail:1.6.6'
implementation 'com.sun.mail:android-activation:1.6.7'
}
パーミッションの追加
AndroidManifest.xmlにインターネット通信を許可するパーミッションを追加する<uses-permission android:name="android.permission.INTERNET" />
strings.xmlに以下の記述を行う
<string name="contact">お問い合わせ</string>
<string name="contact_US">contact</string>
<string name="contact_text">本アプリに関するご質問・ご要望・不具合等のご連絡\nにつきましては下記より必要事項をご記入の上ご連絡\nください。</string>
<string name="Name">Name</string>
<string name="Email">E_mail</string>
<string name="message">Message</string>
<string name="send">Send</string>
activity_main.xmlに以下の記述を行う
※画像はお好みの画像を入れて下さい
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".MainActivity">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
app:cardCornerRadius="10dp"
app:cardElevation="3dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/Header_Image"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/contact"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/contact_us"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contact_US"
android:textColor="@color/black"
android:textSize="35sp"
android:layout_marginTop="40dp"
android:textStyle="italic"
android:typeface="serif"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/Header_Image" />
<TextView
android:id="@+id/contact_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:padding="10dp"
android:text="@string/contact_text"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="italic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contact_us" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/name_layout"
android:layout_width="174dp"
android:layout_height="55dp"
android:layout_marginStart="20dp"
android:layout_marginTop="35dp"
android:layout_marginEnd="10dp"
app:boxStrokeColor="@color/black"
app:hintTextColor="@color/black"
app:layout_constraintEnd_toStartOf="@+id/Email_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contact_text">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/NameText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/Name"
android:singleLine="true"
android:textStyle="bold|italic" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/Email_layout"
android:layout_width="174dp"
android:layout_height="55dp"
android:layout_marginStart="10dp"
android:layout_marginTop="35dp"
android:layout_marginEnd="20dp"
app:boxStrokeColor="@color/black"
app:hintTextColor="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/name_layout"
app:layout_constraintTop_toBottomOf="@+id/contact_text">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/EmailText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/Email"
android:singleLine="true"
android:textStyle="bold|italic" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/Massage_layout"
android:layout_width="368dp"
android:layout_height="87dp"
android:layout_marginStart="8dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="8dp"
app:boxStrokeColor="@color/black"
app:hintTextColor="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name_layout">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/MessageText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/message"
android:textStyle="bold|italic"
/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/Send_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:backgroundTint="@color/black"
android:text="@string/send"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/Massage_layout" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
MainActivity内に以下の記述を行う
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.material.button.MaterialButton;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
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 MainActivity extends AppCompatActivity {
EditText mName;
EditText M_email;
EditText M_message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//アクションバーを非表示にする設定
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.hide();
}
//送信ボタンを取得する
MaterialButton SendButton = findViewById(R.id.Send_button);
SendButton.setOnClickListener(new SendButtonOnClick());
//各種EditTextを取得する
mName = findViewById(R.id.NameText);
M_email = findViewById(R.id.EmailText);
M_message = findViewById(R.id.MessageText);
}
//送信ボタンを押したときに起動するリスナクラス
private class SendButtonOnClick implements View.OnClickListener{
@Override
public void onClick(View view) {
buttonSendEmail();
}
}
private void buttonSendEmail() {
try {
//送信元アドレスを設定する
String sender_Email = "ほげほげ@gmail.com";
//送信元内で作成したアプリパスワードを設定する
String sender_password = "作成した上記gmailアドレスのアプリパスワード";
//送信先アドレスを設定する
String ReceiverEmail = "送信先のメールアドレス";
String Hostname = "smtp.gmail.com";
Properties properties = System.getProperties();
//使用するポート番号と認証方式を入力する
properties.put("mail.smtp.host", Hostname);
properties.put("mail.smtp.port", "587");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.debug", "true");
properties.put("mail.smtp.auth", "true");
//sessionを取得する
final javax.mail.Session session = Session.getInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(sender_Email, sender_password);
}
});
//MimeMessage内に作成したsessionと送信先の情報を設定する
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(ReceiverEmail));
//件名を記載する
mimeMessage.setSubject("テストメール");
//本文を設定する
mimeMessage.setText(("お客様お名前" + System.getProperty("line.separator")
+ mName.getText() + System.getProperty("line.separator")+ System.getProperty("line.separator")
+ "お客様のメールアドレス" + System.getProperty("line.separator") + M_email.getText())
+ System.getProperty("line.separator") + System.getProperty("line.separator")
+ "お問い合わせ内容" + System.getProperty("line.separator") + M_message.getText());
Thread thread = new Thread(() -> {
try {
Transport.send(mimeMessage);
} catch (Exception e) {
e.printStackTrace();
}
});
thread.start();
Log.d("送信", "送信完了です");
onPostExecute();
remove();
}catch (AddressException e) {
Log.e("Error", "AddressException");
e.printStackTrace();
} catch (MessagingException e) {
Log.e("Error", "MessagingException");
e.printStackTrace();
}
}
protected void onPostExecute() {
//画面にメッセージを表示させる
Toast.makeText(MainActivity.this, (String) "送信が完了しました", Toast.LENGTH_LONG).show();
}
//メールの送信が完了したらテキストを空にする処理
protected void remove() {
M_message.setText("");
mName.setText("");
M_email.setText("");
}
}
実行結果
「送信」ボタンをタップすると、メールが送信され画面にトーストが表示されます。
正常に受信した場合
参考サイト
https://qiita.com/Rabbit_Program/items/9df03bf2c1885561a5bd
https://qiita.com/nozaki-sankosc/items/3f52c011ffd5db546763
https://www.shookuro.com/entry/java-mail-gmail