0

I have a simple android one button app that send automatic email when the button is pressed. The app works fine in emulator but on real device (samsung gt-n7000) the app won't work. The device is connected to wi-fi only.

here are the codes:

import java.util.Date;
import java.util.Properties;

import javax.activation.CommandMap;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.MailcapCommandMap;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class GMailSender extends javax.mail.Authenticator {
    private String _user; 
      private String _pass; 

      private String[] _to; 
      private String _from; 

      private String _port; 
      private String _sport; 

      private String _host; 

      private String _subject; 
      private String _body; 

      private boolean _auth; 

      private boolean _debuggable; 

      private Multipart _multipart; 


      public GMailSender() { 
        _host = "smtp.gmail.com"; // default smtp server 
        _port = "465"; // default smtp port 
        _sport = "465"; // default socketfactory port 

        _user = ""; // username 
        _pass = ""; // password 
        _from = ""; // email sent from 
        _subject = ""; // email subject 
        _body = ""; // email body 

        _debuggable = false; // debug mode on or off - default off 
        _auth = true; // smtp authentication - default on 

        _multipart = new MimeMultipart(); 

        // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added. 
        MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); 
        mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
        mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 
        mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); 
        mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); 
        mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822"); 
        CommandMap.setDefaultCommandMap(mc); 
      } 

      public GMailSender(String user, String pass) { 
        this(); 

        _user = user; 
        _pass = pass; 
      } 

      public boolean send() throws Exception { 
        Properties props = _setProperties(); 

        if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) { 
          Session session = Session.getInstance(props, this); 

          MimeMessage msg = new MimeMessage(session); 

          msg.setFrom(new InternetAddress(_from)); 

          InternetAddress[] addressTo = new InternetAddress[_to.length]; 
          for (int i = 0; i < _to.length; i++) { 
            addressTo[i] = new InternetAddress(_to[i]); 
          } 
            msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); 

          msg.setSubject(_subject); 
          msg.setSentDate(new Date()); 

          // setup message body 
          BodyPart messageBodyPart = new MimeBodyPart(); 
          messageBodyPart.setText(_body); 
          _multipart.addBodyPart(messageBodyPart); 

          // Put parts in message 
          msg.setContent(_multipart); 

          // send email 
          Transport.send(msg); 

          return true; 
        } else { 
          return false; 
        } 
      } 

      public void addAttachment(String filename) throws Exception { 
        BodyPart messageBodyPart = new MimeBodyPart(); 
        DataSource source = new FileDataSource(filename); 
        messageBodyPart.setDataHandler(new DataHandler(source)); 
        messageBodyPart.setFileName(filename); 

        _multipart.addBodyPart(messageBodyPart); 
      } 

      @Override 
      public javax.mail.PasswordAuthentication getPasswordAuthentication() {
        return  new javax.mail.PasswordAuthentication(_user,_pass); 
      } 

      private Properties _setProperties() { 
        Properties props = new Properties(); 

        props.put("mail.smtp.host", _host); 

        if(_debuggable) { 
          props.put("mail.debug", "true"); 
        } 

        if(_auth) { 
          props.put("mail.smtp.auth", "true"); 
        } 

        props.put("mail.smtp.port", _port); 
        props.put("mail.smtp.socketFactory.port", _sport); 
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
        props.put("mail.smtp.socketFactory.fallback", "false"); 

        return props; 
      } 

      // the getters and setters 
      public String getBody() { 
        return _body; 
      } 

      public void setBody(String _body) { 
        this._body = _body; 
      }

    public String[] get_to() {
        return _to;
    }

    public void set_to(String[] _to) {
        this._to = _to;
    }

    public String get_from() {
        return _from;
    }

    public void set_from(String _from) {
        this._from = _from;
    }

    public String get_subject() {
        return _subject;
    }

    public void set_subject(String _subject) {
        this._subject = _subject;
    } 

    } 

MainClass:

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

public class MainActivity extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void sending(View v) {
           GMailSender mailsender = new GMailSender("example@gmail.com", "password");

           String[] toArr = { "mussa2kasssim@hotmail.com" };
           mailsender.set_to(toArr);
           mailsender.set_from("example@gmail.com");
           mailsender.set_subject("This is an email sent using my Mail JavaMail wrapper from an Android device.");
           mailsender.setBody("Hello World!");
          // mailsender.send();

         try {
               //mailsender.addAttachment("/sdcard/filelocation");

               if (mailsender.send()) {
                   Toast.makeText(MainActivity.this,
                           "Email was sent successfully.",
                           Toast.LENGTH_LONG).show();
               } else {
                   Toast.makeText(MainActivity.this, "Email was not sent.",
                           Toast.LENGTH_LONG).show();
               }
           } catch (Exception e) {

               Log.e("MailApp", "Could not send email", e);
           }
       } 
    }

NB: "example@gmail.com" and "password" are replaced with authentic values.

Please help. Thank you

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.nikhil.emailing"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.emailing.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.emailing.EmailActivity"
            android:label="@string/title_activity_email" >
        </activity>
    </application>

</manifest>

XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:onClick="sending"
        android:text="Email" />

</RelativeLayout>

Error Log:

11-07 12:43:07.616: ERROR/lights(1845): write_int: path/sys/devices/virtual/sec/sec_touchkey/brightness, value 1
11-07 12:43:07.841: ERROR/MailApp(24559): Could not send email
11-07 12:43:07.841: ERROR/MailApp(24559): android.os.NetworkOnMainThreadException
11-07 12:43:07.841: ERROR/MailApp(24559):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
11-07 12:43:07.841: ERROR/MailApp(24559):     at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
11-07 12:43:07.841: ERROR/MailApp(24559):     at java.net.InetAddress.getLocalHost(InetAddress.java:371)
11-07 12:43:07.841: ERROR/MailApp(24559):     at javax.mail.internet.InternetAddress.getLocalAddress(InternetAddress.java:517)
11-07 12:43:07.841: ERROR/MailApp(24559):     at javax.mail.internet.UniqueValue.getUniqueMessageIDValue(UniqueValue.java:99)
11-07 12:43:07.841: ERROR/MailApp(24559):     at javax.mail.internet.MimeMessage.updateMessageID(MimeMessage.java:2054)
11-07 12:43:07.841: ERROR/MailApp(24559):     at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2076)
11-07 12:43:07.841: ERROR/MailApp(24559):     at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2042)
11-07 12:43:07.841: ERROR/MailApp(24559):     at javax.mail.Transport.send(Transport.java:117)
11-07 12:43:07.841: ERROR/MailApp(24559):     at com.nikhil.emailing.GMailSender.send(GMailSender.java:105)
11-07 12:43:07.841: ERROR/MailApp(24559):     at com.nikhil.emailing.MainActivity.sending(MainActivity.java:31)
11-07 12:43:07.841: ERROR/MailApp(24559):     at java.lang.reflect.Method.invokeNative(Native Method)
11-07 12:43:07.841: ERROR/MailApp(24559):     at java.lang.reflect.Method.invoke(Method.java:511)
11-07 12:43:07.841: ERROR/MailApp(24559):     at android.view.View$1.onClick(View.java:3095)
11-07 12:43:07.841: ERROR/MailApp(24559):     at android.view.View.performClick(View.java:3627)
11-07 12:43:07.841: ERROR/MailApp(24559):     at android.view.View$PerformClick.run(View.java:14329)
11-07 12:43:07.841: ERROR/MailApp(24559):     at android.os.Handler.handleCallback(Handler.java:605)
11-07 12:43:07.841: ERROR/MailApp(24559):     at android.os.Handler.dispatchMessage(Handler.java:92)
11-07 12:43:07.841: ERROR/MailApp(24559):     at android.os.Looper.loop(Looper.java:137)
11-07 12:43:07.841: ERROR/MailApp(24559):     at android.app.ActivityThread.main(ActivityThread.java:4511)
11-07 12:43:07.841: ERROR/MailApp(24559):     at java.lang.reflect.Method.invokeNative(Native Method)
11-07 12:43:07.841: ERROR/MailApp(24559):     at java.lang.reflect.Method.invoke(Method.java:511)
11-07 12:43:07.841: ERROR/MailApp(24559):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
11-07 12:43:07.841: ERROR/MailApp(24559):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
11-07 12:43:07.841: ERROR/MailApp(24559):     at dalvik.system.NativeStart.main(Native Method)
11-07 12:43:08.786: ERROR/DataRouter(1690): usb connection is true 
11-07 12:43:08.786: ERROR/DataRouter(1690): DSR is ON. Don't send DTR ON.
11-07 12:43:09.121: ERROR/lights(1845): write_int: path /sys/devices/virtual/sec/sec_touchkey/brightness, value 2
11-07 12:43:09.741: ERROR/AlarmManagerService(1845): android_server_AlarmManagerService_set to type=1, 1383830133.779000000
11-07 12:43:09.896: ERROR/AlarmManagerService(1845): android_server_AlarmManagerService_set to type=1, 1383828192.898000000
11-07 12:43:10.791: ERROR/DataRouter(1690): usb connection is true 
11-07 12:43:10.791: ERROR/DataRouter(1690): DSR is ON. Don't send DTR ON.
11-07 12:43:12.791: ERROR/DataRouter(1690): usb connection is true 
11-07 12:43:12.791: ERROR/DataRouter(1690): DSR is ON. Don't send DTR ON.
11-07 12:43:12.896: ERROR/AlarmManagerService(1845): android_server_AlarmManagerService_set to type=1, 1383830133.779000000
11-07 12:43:13.036: ERROR/AlarmManagerService(1845): android_server_AlarmManagerService_set to type=1, 1383828196.040000000
  • How exactly doesn't it work? Does it crash? Does it not do what you want it to (in which case, what does it do, and what do you want it to do)? – Dennis Meng Nov 06 '13 at 18:24
  • Please post error log. – Siddharth_Vyas Nov 07 '13 at 04:08
  • There is no any error and the app doesn't crash. It just doesn't do the task (sending email) on the real device. Once the button is clicked, nothing happens, Please help . . . Thank u – Mussa Kassim Nov 07 '13 at 12:32
  • I figured out from another post. The device was blocking my app to access the internet. For some security policies, I had to put a piece of code in the main class to by-pass the policy. The code was: if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } – Mussa Kassim Nov 07 '13 at 12:55

3 Answers3

1

The exception says android.os.NetworkOnMainThreadException

That means network related tasks should not be performed on main thread (UI thread specifically). Run it on background thread and it will work.

Bette Devine
  • 1,196
  • 1
  • 9
  • 23
  • This behaviour has been introduced in some higher Android version (cannot recall which one now), so I guess that's the reason it works in the emulator and not on the real device. – Ridcully Nov 07 '13 at 13:08
0

The related task should be performed in AsyncTask.

Harshit Rathi
  • 1,862
  • 2
  • 18
  • 25
0

It has to do with some ThreadPolicy, I read it from another post. It basically blocks connection that the app initiates. So to disable this policy, I had to put this piece of code in onCreate() of the activity using the connection.

The code is:

if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
          }

And it works as expected :))