Please Enable JavaScript!
Gon[ Enable JavaScript ]

구글에서 GMail 계정을 이용해 SMTP 로 안드로이드 메일보내기

안드로이드 개발
반응형

구글에서 GMail 계정을 이용해 SMTP 로 안드로이드 메일보내기

 

개발환경 : JDK 1.5, eclipse-Galieo, window XP, Google APIs 2.1

 

구글의 GMail POP3, IMAP, SMTP 를 지원한다. POP3 가 된다는 말은 클라이언트에서

메일을 읽어올수 있으며, SMTP 를 사용하여 메일을 보낼수 있다. 그래서 아래에 설명될

안드로이드에서 메일을 보내기는 GMail SMTP 를 이용해 보내는 예제이다.

 

전제조건이 있다. 먼저 GMail 계정이 있어야 한다. 가입하고 등록된 계정으로 테스트

하도록 한다. 그리고 메일보내기 기능은 안드로이드 SDK 로는 해결이 안되므로 필요한

3가지 jar 파일이 필요하다.

 

1. 자바메일을 보내기 위한 jar 다운로드와 패스설정

 

위에서 말했듯이 기본적으로 제공되는 jar 에서는 메일 보내기를 할수 없다.

그래서 다음 3가지를 다운받아야 한다.

Download them from :

http://javamail-android.googlecode.com/files/mail.jar

http://javamail-android.googlecode.com/files/activation.jar

http://javamail-android.googlecode.com/files/additionnal.jar

 

다운받은 파일을 프로젝트내에 적당한 폴더를 만들고 복사한다.

그리고 Build path 를 걸어주기 위해 eclipse > Preferences > Java Build Path  화면으로

이동한다. Libraries 탭을 클릭해서 화면을 열고 다운받아 복사한 폴더에 있는 3 가지 jar

링크하면 된다. path 를 걸어 주는 방법은 몇가지가 있다. 간단하게 Add External JARS…

메뉴를 통해 바로 파일을 선택하고 링크하는 방법이 있다.

설정이 끝나고 나서 왼쪽 Explorer 창을 보게 되면 Referenced Libraries 폴더가 생긴 것을

볼수 있다. 이것은 외부 라이브러리를 참조하려고 위와 같이 패스를 설정하면 자동으로

생기게 된다. 기본 구글 API 로 해결하지 못하는 기능이나 개발 패키지를 jar로 묶어

사용하고자 할 때 유용하게 쓰일수 있다

Build path 를 설정하는 방법은 이외에도 Add Library.. 버튼을 클릭해 사용자 정의

라이브러리를 등록할수도 있다

2. AndroidManifest.xml permission 등록

 

인터넷사용을 위한 permission android.permission.INTERNET 을 등록한다.

<uses-permission android:name="android.permission.INTERNET" ></uses-permission>

 

3. 간략한 소스 분석

 

메일 소스는 gamil smtp를 이용해 보내기 때문에 gmail 로그인 계정이 필요하다. 이것을

넣는 소스가 있다. 상속받은 javax.mail.Authenticator 클래스의 함수를 오버로딩해서

유저와 패스워드를 셋팅하고 넘겨준다

protected PasswordAuthentication getPasswordAuthentication() {  
        return new PasswordAuthentication(user, password);  
}

클래스는 2개이며 Activity 화면을 구현한 것과 메일 보내기 기능만 있는 클래스 하나다.

일반 java 메일 보내기와 거의 동일하므로 소스 분석하는 일은 그렇게 어렵지 않을 것이다.

아직 다양하게 방법들을 테스트 해보지 않았다. 내가 당장 하고 싶은건 이미지 파일을 동봉해서

보내는 것인데 아직 구현하지 못했다.

 

환경설정을 위한 정보는 Properties 클래스를 사용하였다. 그리고 그 Properties session

에 저장하고 공통적으로 사용한다
Properties props = new Properties();  
props.setProperty("mail.transport.protocol", "smtp");  
props.setProperty("mail.host", mailhost);  
props.put("mail.smtp.auth", "true");  
props.put("mail.smtp.port", "465");  
props.put("mail.smtp.socketFactory.port", "465");

4. 결과 확인

 

Activity 를 실행하고 화면에서 메일 보내기를 클릭한다. 그러면 설정해 놓은 GMail 계정으로

메일을 보냈다.

메일 사이트로 가 결과를 확인한다.

5. 전체 소스


/* ============================= */ 

/*          send_mail.xml          */ 

/* ============================= */

 <?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical" 

    android:layout_width="fill_parent" 

    android:layout_height="fill_parent"  > 

       <TextView   

           android:layout_width="fill_parent"  

           android:layout_height="wrap_content"  

           android:text="안녕하세요 "/>        

     <Button 

        android:id="@+id/send"       

        android:layout_width="wrap_content" 

        android:layout_height="wrap_content" 

        android:layout_gravity="center_horizontal"   

        android:text="메일 보내기" /> 

</LinearLayout> 

 
////    GMailSender.class 
package com.success.sample;

import java.io.ByteArrayInputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.security.Security;  
import java.util.Properties;  
  
import javax.activation.DataHandler;  
import javax.activation.DataSource;  
import javax.mail.Message;  
import javax.mail.PasswordAuthentication;  
import javax.mail.Session;  
import javax.mail.Transport;  
import javax.mail.internet.InternetAddress;  
import javax.mail.internet.MimeMessage;  
  
public class GMailSender extends javax.mail.Authenticator {  
    private String mailhost = "smtp.gmail.com";  
    private String user;  
    private String password;  
    private Session session;  
  
    public GMailSender(String user, String password) {  
        this.user = user;  
        this.password = password;  
  
        Properties props = new Properties();  
        props.setProperty("mail.transport.protocol", "smtp");  
        props.setProperty("mail.host", mailhost);  
        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");  
  
        session = Session.getDefaultInstance(props, this);  
    }  

    protected PasswordAuthentication getPasswordAuthentication() {  
        return new PasswordAuthentication(user, password);  
    }  
  
    public synchronized void sendMail(String subject, String body, String sender, String recipients) throws Exception {  
        MimeMessage message = new MimeMessage(session);  
        DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));  
        message.setSender(new InternetAddress(sender));  
        message.setSubject(subject);  
        message.setDataHandler(handler);  
        if (recipients.indexOf(',') > 0)  
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));  
        else  
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));  
        Transport.send(message);  
    }  
  
    public class ByteArrayDataSource implements DataSource {  
        private byte[] data;  
        private String type;  
  
        public ByteArrayDataSource(byte[] data, String type) {  
            super();  
            this.data = data;  
            this.type = type;  
        }  
  
        public ByteArrayDataSource(byte[] data) {  
            super();  
            this.data = data;  
        }  
  
        public void setType(String type) {  
            this.type = type;  
        }  
  
        public String getContentType() {  
            if (type == null)  
                return "application/octet-stream";  
            else  
                return type;  
        }  
  
        public InputStream getInputStream() throws IOException {  
            return new ByteArrayInputStream(data);  
        }  
  
        public String getName() {  
            return "ByteArrayDataSource";  
        }  
  
        public OutputStream getOutputStream() throws IOException {  
            throw new IOException("Not Supported");  
        }  
    }  
}


////////       MailSend.class           

package com.success.sample;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.success.R;
  
public class SendMail extends Activity {  
    /** 
     * Called with the activity is first created. 
     */  
    @Override  
    public void onCreate(Bundle icicle) {  
        super.onCreate(icicle);  
        setContentView(R.layout.send_mail);  
        final Button send = (Button) this.findViewById(R.id.send);  
          
        send.setOnClickListener(new View.OnClickListener() {  
            public void onClick(View view) {  
            GMailSender sender = new GMailSender("id@gmail.com","storm200"); // SUBSTITUTE HERE                    
                try {  
                    sender.sendMail(  
                            "메일제목 !!",   //subject.getText().toString(),   
                            "메일 본문입니다..~~ ",           //body.getText().toString(),   
                            "id@gmail.com",          //from.getText().toString(),  
                            "id@naver.com"            //to.getText().toString()  
                            );  
                } catch (Exception e) {  
                    Log.e("SendMail", e.getMessage(), e);  
                }  
            }  
        });  
    }  
}

반응형
Posted by 녹두장군

댓글을 달아 주세요

  1. 이전 댓글 더보기
  2. 푸르르미 2011.06.16 13:24  댓글주소  수정/삭제  댓글쓰기

    님 소스를 예제 파일로 그냥 돌릴려고 하는데
    id 에 제 계정을 넣고 받는 주소에 제 다른 주소를 넣었는데
    안되네요
    avr 로 실행했는데 안되는건가요?

  3. 카프리 2011.06.24 14:42  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 :)
    블로그 글보고 많은 도움 받았습니다.
    혹시 첨부파일 보내기 예제를 포스팅하실 계획은 없으신가요?

    • 녹두장군 2011.07.09 20:31  댓글주소  수정/삭제

      조만간 올리도록 하겠습니다..
      요즘 새로 프로젝트 시작해서 주말도 없네요 ^^

  4. seman 2011.06.28 16:33  댓글주소  수정/삭제  댓글쓰기

    안녕하세요~^^
    정말 능력자시네요...ㄷㄷㄷ
    근데 제가 아직 초보라 소스를 그대로 가져와서 겔2로 돌렸는데요
    안드로이드 2.2인것만 빼면 개발환경도 똑같구요...

    "javax.mail.AuthenticationFailedException" 에러가 떠버리네요..ㅠ.ㅠ

    "Transport.send(message);" <-- 이부분에서요....흑..

    혹시 왜그런지 조언좀 해주실 수 있을까요??????^^

  5. 복땡이 2011.08.06 22:57  댓글주소  수정/삭제  댓글쓰기

    좋은 글 잘보았습니다.
    해당 라이브러리를 사용하려고 라이센스를 확인 하였는데..
    GPL이군요 ㅠㅠ 그것이 너무나 아쉽다고 생각이 듭니다.
    다음에 오픈소스를 진행하게 된다면 그때 사용여부를 다시 검토해야 겠다고 생각이 듭니다.

    훌륭한 포스트를 공개해주셔서 감사합니다.

  6. 만나서반갑습니다. 2011.08.08 19:02  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.
    매번 블로그 와서 좋은 정보 많이 배워 갑니다 ^^
    뿐만 아니라 프로젝트를 진행하는데 크게 도움이 되었습니다.
    이미지를 첨부하여 메일전송한 소스 있으시면
    포스팅 해주시면 안될까요 ^^?;;;
    아니면 정보좀 공유해 주셨으면 감사하겠습니다 ^^

    • 곤일 2011.09.14 15:37  댓글주소  수정/삭제

      저도 파일 첨부하는 것 하고 있는데 아직 구현은 못했습니다.
      근데 이클립스에서 제공하는 내부함수목록을 통해서
      .setFileName을 쓰면 빈 파일이 첨부되는 것은 확인했습니다 ㅋ;;
      이제 실제 파일 경로랑 연결만 시키면 될듯....
      어떻게 해야할까요 ㅋㅋㅋㅋㅋ
      혹시 해결하시면 댓글 좀 ㅋㅋ

  7. 곤일 2011.09.14 22:57  댓글주소  수정/삭제  댓글쓰기

    http://www.androes.com/133

    이 사이트에 가니깐 파일첨부하는 것까지 나와있네요!!!
    파일 첨부하는 것으로 찾으시는 분들은 이글 참고하시면 될 것 같아요 ^^

  8. 차니 2011.10.02 20:03  댓글주소  수정/삭제  댓글쓰기

    ㅠ.ㅠ
    이상하게 메일이 안보내 지네요..
    코드 에러 없고..
    아무말도 안뜨는데
    버튼 눌러도 메일이 안보내져요..

    아이디 비번, 현재 제껄로 다 해봤는데요

    • 낭천 2011.11.09 13:37  댓글주소  수정/삭제

      10월글이라 이미 해결하셨을 듯 하지만, 제 경험에 의하면
      아마 Try문이 실행안되고 catch문이 실행되고 있을겁니다, 그러면 버튼을누르면 버튼을 눌리는데 아무것도 안일어나고 메일도 안가죠. 이때 error내용을 catch문에서 확인해보면 permission이 안되어있다고 나옵니다. 아마 퍼미션이 제대로 추가가 안됬을겁니다.
      이문제가 아니라 버튼을 눌렀을때 에뮬레이터가 멈춘다고 하면 아마 에뮬레이터라서 안되는걸겁니다

  9. 효성 2011.10.18 01:57  댓글주소  수정/삭제  댓글쓰기

    님의 코드는 정말 많이 도움이 되네요.. 감사합니다.

    혹시 안드로이드 폰에 이미 저장한 지메일 아이디와 패스워드 값을 받아와서 프로그램을 실행시킬 수 없을까요?
    설명해 주신 코드에서는 코드 내부에 아이디와 패스 워드를 넣어서 이메일 송신 기능을 수행하던데요...

    그리고 혹시 지메일 수신 기능은 안되나요?
    아니면 위에 파일 첨부한 .jar 파일의 클래스를 이용하면 지메일 수신 기능이 가능할까요?

    꼭 답변 부탁드릴게요
    위의 설명과 코드는 정말로 감사합니다..

  10. 낭천 2011.11.09 13:31  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 좋은글 감사합니다. 안드로이드 사이드에도 글 올리셨더라구요 ^^
    초보라 우여곡절끝에 에러없에고 실행까진 성공했는데 버튼누르면 엄청 기다렸다가 에러가 뜨네요
    안드로이드 사이드에 같은증상인분의 리플을보니까 어플에서는 안된다는 것 같던데 내일 집에서 단말기 가져와서 확인해봐야겠네요 ^^

  11. 낭천 2011.11.09 17:06  댓글주소  수정/삭제  댓글쓰기

    네이버 블로그에 일기처럼 쓰고있는데 적으신 소스 출처와 주소 링크 걸어놓고 소스를 기재했는데 말씀해주시면 비밀공개로 하겠습니다.
    http://blog.naver.com/ktshas/80145044365

  12. 2012.12.12 20:40  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  13. 4V4NTG4RDE 2013.03.07 14:53  댓글주소  수정/삭제  댓글쓰기

    정리가 정말 잘되어 있네요. 도움 많이 되었습니다.

    저도 위와같은 방법을 사용하여 메일 보내기를 테스트한 결과, 에뮬레이터 안드로이드 2.0 에서는 제대로 동작하였습니다.

    하지만 제 갤럭시S3 에서는 동작하지 않는것을 확인하였습니다. 그래서 에뮬레이터 안드로이드 4.2 버전에서 테스트를 다시 진행한 결과 동작하지 않았습니다.

    아무래도 버전에 따른 동작 방법이 달라진것 같습니다.

    혹시 이에 대해 아시는게 있으시면 답변 주시면 감사하겠습니다.^^

    • kkki 2013.04.04 18:16  댓글주소  수정/삭제

      이글을 읽으실지는 모르겠지만 지금 현버전에서는 스레드를 메인에서 돌릴수 없어서 그런 상태가 발생하는 겁니다. Transport.send(message);
      이 부분을 어싱크로 하셔서 백그라운드에서 돌리시면 잘 돌아가는걸 확인하실수 잇으실겁니다. 혹 궁금한게 있으면 다시 댓글달아주세요.

  14. 태경 2013.06.16 03:10  댓글주소  수정/삭제  댓글쓰기

    저도 4.2 안드로이드 버전에서는 안돌아가는데요

    Transport.send(message);
    이 부분을 어싱크로 하셔서 백그라운드에서 돌리시면 잘 돌아가는걸 확인하실수 잇으실겁니다

    이부분을 잘좀 설명해주시면 안될까요 ㅠ

    • Favicon of https://mainia.tistory.com 녹두장군 2015.12.23 07:38 신고  댓글주소  수정/삭제

      비동기를 말하는 것입니다. 동기로 하시면 프로그램이 멈춰버리겠죠. 어싱크(비동기) 는 내가 다른 작업을 할 수 있고 응답이 올 때 까지 기다리지 않아도 된다는 말입니다.

  15. 초보 2014.05.06 21:39  댓글주소  수정/삭제  댓글쓰기

    댓글 읽고 연락드립니다 ...ㅠ
    어싱크로 하라는게 어떤 말씀이신지 이해가 안가서 그렇습니다 ..ㅠ 안드로이드 초보자입니다 ㅠㅠ

  16. 초보 2015.04.05 16:43  댓글주소  수정/삭제  댓글쓰기

    import com.success.R; 여기서 com.sucess 에러나는데 어떻게 해야하나요 ㅠ




    • Favicon of https://mainia.tistory.com 녹두장군 2015.04.05 19:12 신고  댓글주소  수정/삭제

      com.success.R 은 리소스를 말합니다. 그러니가 com.success는
      패키지주소가 되겠죠. 님의 패키지 주소를 넣으시고, 아니면
      지운후에 단축키로 import 시키시면 됩니다.

  17. hiz 2015.07.03 11:05  댓글주소  수정/삭제  댓글쓰기

    잘 보고 잘 배워갑니다~ 감사합니다!

  18. 김승규 2015.10.09 03:57  댓글주소  수정/삭제  댓글쓰기

    이 방법으로 이미지(사진)는 못보내나요>??

  19. wook 2015.12.22 19:47  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 좋은 정보 감사합니다.
    지금 try문까지는 들어오는거 같은데 메일이 안오네요..
    쥐메일 설정 다 한거 같은데 POP 사용 IMAP 사용 다했는데..

    뭐때문에 그런지 알수 있을까요?

  20. 녹두장군님짱 2016.01.06 23:29  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 녹두장군님 항상 포스팅 잘 보고 있습니다!
    저는 대학생 개발자 인데요 녹두장군님의 소스코드를 참고하여 앱을 개발하던 중 오류가 발생하였습니다.

    오류가 두개가 나는데

    FATAL EXCEPTION: Thread-18448
    Process: com.example.project2_2, PID: 18150
    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

    이 오류와

    E/SendMail: null
    javax.mail.AuthenticationFailedException

    이렇게 두가지 오류가 뜹니다.

    첫번째 오류의 원인은 쓰레드가 중복이 되서 그런거 같은데
    어떻게 해야할 지 모르겠습니다ㅜㅜ
    어떻게 해야 두 오류를 수정할 수 있을까요?
    조언 부탁드립니다!

  21. user 2016.11.30 14:43  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 늦었지만 답변가능하신가요?ㅠㅠ
    이메일 자동전송이 되도록 하려고 그대로 따라했습니다.
    그런데 인터넷연결을 확인해달라는 Toast메세지만 나타납니다ㅜㅜ
    에러를 출력한 결과 javax.mail.AuthenticationFailedException으로 나타납니다ㅜㅜ

    조언부탁드립니다ㅜㅜ!