Tuesday, October 23, 2012

Sending Mail from Android

You can use this API for sending mail
http://www.oracle.com/technetwork/java/javamail/index.html


Place this Mail.java in the project.
And call this Mail using

public class MailToOutlet extends AsyncTask<OrderInRequest, Void, Void> {
@Override
protected void onPreExecute() {
System.out.println("Sending Mail");
super.onPreExecute();
}

@Override
protected Void doInBackground(OrderInRequest... orderInRequest) {

try {
Mail m = new Mail("EMAILADDRESS@gmail.com", "PASSWORD");

/*
to send mail to multiple email address
String[] toArr = { "EMAILADDRESS@gmail.com"};
*/

String toAr = null;
toAr = orderInRequest[0].getOutletsAddress();
String toArr[]={toAr};
m.set_to(toArr);
m.set_from("EMAILADDRESS@gmail.com");
m.set_subject("This is an email sent using JavaMail from an Android device.");

m.set_body("BODY OF YOUR EMAIL");

m.send();

} catch (Exception e) {
e.printStackTrace();
}
return null;
}

@Override
protected void onPostExecute(Void result) {

System.out.println("Mail Sent successfully");
super.onPostExecute(result);

}
}



Mail.java

package com.jugal.sampleMail;

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.PasswordAuthentication;
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 Mail extends javax.mail.Authenticator {
private String _user;
private String _pass;

public String[] _to;
public 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 Mail() {
_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);
}

// Another constructor... just in-case you want to pass user-name and
// password while instantiating the class.
// It overrides the other
public Mail(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;
}
}

// You can call this method at any time if you want to add an attachment,
// but make sure you call it before the send method.
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 PasswordAuthentication getPasswordAuthentication() {
return new 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;
}

public String get_user() {
return _user;
}

public void set_user(String _user) {
this._user = _user;
}

public String get_pass() {
return _pass;
}

public void set_pass(String _pass) {
this._pass = _pass;
}

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_port() {
return _port;
}

public void set_port(String _port) {
this._port = _port;
}

public String get_sport() {
return _sport;
}

public void set_sport(String _sport) {
this._sport = _sport;
}

public String get_host() {
return _host;
}

public void set_host(String _host) {
this._host = _host;
}

public String get_subject() {
return _subject;
}

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

public String get_body() {
return _body;
}

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

public boolean is_auth() {
return _auth;
}

public void set_auth(boolean _auth) {
this._auth = _auth;
}

public boolean is_debuggable() {
return _debuggable;
}

public void set_debuggable(boolean _debuggable) {
this._debuggable = _debuggable;
}

public Multipart get_multipart() {
return _multipart;
}

public void set_multipart(Multipart _multipart) {
this._multipart = _multipart;
}

}

Friday, February 3, 2012

Custom ListView with sliding view for each list

We shall look at creating a custom list view – a custom layout, a custom row layout and how we bind the custom data holder to these layouts. The custom row layout consists of five textViews and an Image Button.


At the end of this tutorial you would be able to perform a sliding view for each listview like this.


Before Click

After Click




First let us create a list view object file which contains a list view - custom_list_view.xml.


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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
Creating a list view will
look like this (in eclipse)
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <ListView
        android:id="@+id/listView1:list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>


</LinearLayout>




Note that it must contain a ListView object with android:id="@id/android:list"




Now we will declare how each row in this ListView should be displayed by creating a new xml file –custom_row_view.xml


custom_row_view.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@+id/linearLayout3"
        android:orientation="vertical" >


        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />


        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Small Text"
            android:textAppearance="?android:attr/textAppearanceSmall" />


        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Small Text"
            android:textAppearance="?android:attr/textAppearanceSmall" />
    </LinearLayout>


<LinearLayout
        android:id="@+id/linearLayout3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/linearLayout1"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:baselineAligned="false" >


<ImageView
          android:id="@+id/imageView1"
          android:layout_width="25dp"
          android:layout_height="match_parent"
          android:background="@drawable/slide_image"
          android:onClick="myClickHandler"
          android:src="@drawable/double_arrow_left" android:padding="5px"/>




        <LinearLayout
            android:id="@+id/linearLayout2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/bg_brown_color"
            android:orientation="vertical"
            android:paddingLeft="5px" >


            <TextView
                android:id="@+id/textView4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="18dp"
                android:layout_marginRight="16dp"
                android:text="@string/replies"
                android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="@color/black_color"/>


            <TextView
                android:id="@+id/textView5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/views"
                android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="@color/black_color"/>
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

      
Note that the visibility of the LinearLayout is set to gone i.e. it does not get displayed initially. We will make it visible when the imageButton will be clicked that we will perform in the Java file

Now we will make the java file which will help us display the custom layout integrating the custom_row_layout into the listView 
I plan to have 6 items one below the other in each row (1-ImageView, 5-textViews). So, here is the declaration for the same – CustomListView.java


CustomListView.java

package org.learning;

import java.util.*;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class LearningActivity extends Activity {
     ListView lw;
private SimpleAdapter adapter;
private ArrayList<HashMap<String, String>> list;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_list_view);
        lw=(ListView) findViewById(R.id.listView1_list);
        list = new ArrayList<HashMap<String,String>>();
        populateList();
        adapter = new SimpleAdapter(
        this,
        list,
        R.layout.custom_row_view,
        new String[] {"title","threadID","startedBy"},
        new int[] {R.id.textView1,R.id.textView2,R.id.textView3}
        );
        lw.setAdapter(adapter);
        lw.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//Code for performing the on list view listener.
}
});
        findViewById(R.id.linearLayout1);
    }
    public void myClickHandler(View v) {
    LinearLayout vwParentRow = (LinearLayout)v.getParent();
    ImageView iv= (ImageView) vwParentRow.getChildAt(0);
    LinearLayout lw=(LinearLayout) vwParentRow.getChildAt(1);
    if(lw.getVisibility()==View.GONE){
    lw.setVisibility(View.VISIBLE);
    iv.setImageResource(R.drawable.double_arrow_right);
        }else{
            lw.setVisibility(View.GONE);
    iv.setImageResource(R.drawable.double_arrow_left);
    }
    }
    
    void populateList(){
    HashMap<String,String> temp = new HashMap<String,String>();
    temp.put("title","Title");
temp.put("threadID","Sub - Title - 1");
temp.put("startedBy","Sub - Title - 2");
list.add(temp);
     temp.put("title","Title");
temp.put("threadID","Sub - Title - 1");
temp.put("startedBy","Sub - Title - 2");
list.add(temp);
temp.put("title","Title");
temp.put("threadID","Sub - Title - 1");
temp.put("startedBy","Sub - Title - 2");
list.add(temp);
    }
}

Here we have set the default view to custom_list_view. Then, using the  SimpleAdapter, we have set the context, the list containing the data for display, the  custom_row_view, the keys by which the data has to be fetched from the list, the TextViews into which the corresponding data has to be displayed. Now execute and you will have a custom list view and this is what u will see:



You can download the complete source code here.