com.wit.android.support.content.intent.EmailIntent.java Source code

Java tutorial

Introduction

Here is the source code for com.wit.android.support.content.intent.EmailIntent.java

Source

/*
 * =================================================================================================
 *                Copyright (C) 2013 - 2014 Martin Albedinsky [Wolf-ITechnologies]
 * =================================================================================================
 *         Licensed under the Apache License, Version 2.0 or later (further "License" only).
 * -------------------------------------------------------------------------------------------------
 * You may use this file only in compliance with the License. More details and copy of this License
 * you may obtain at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * You can redistribute, modify or publish any part of the code written within this file but as it
 * is described in the License, the software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES or CONDITIONS OF ANY KIND.
 *
 * See the License for the specific language governing permissions and limitations under the License.
 * =================================================================================================
 */
package com.wit.android.support.content.intent;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.util.Patterns;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

/**
 * <h3>Class Overview</h3>
 * Intent builder specialized to create E-MAIL intents.
 *
 * @author Martin Albedinsky
 */
public class EmailIntent extends BaseIntent<EmailIntent> {

    /**
     * Interface ===================================================================================
     */

    /**
     * Constants ===================================================================================
     */

    /**
     * Log TAG.
     */
    private static final String TAG = "EmailIntent";

    /**
     * Flag indicating whether the debug output trough log-cat is enabled or not.
     */
    // private static final boolean DEBUG_ENABLED = true;

    /**
     * Flag indicating whether the output trough log-cat is enabled or not.
     */
    // private static final boolean LOG_ENABLED = true;

    /**
     * Uri scheme for <b>e-mail</b> targeting intents.
     * <p>
     * Constant value: <b>mailto:</b>
     */
    public static final String SCHEME = "mailto:";

    /**
     * Static members ==============================================================================
     */

    /**
     * Matcher for valid e-mail address.
     */
    protected static final Matcher EMAIL_MATCHER = Patterns.EMAIL_ADDRESS.matcher("");

    /**
     * Members =====================================================================================
     */

    /**
     * E-mail parameter.
     */
    private CharSequence mSubject, mMessage;

    /**
     * Array with e-mail addresses.
     */
    private List<String> mEmails;

    /**
     * Array with e-mail addresses for carbon copy.
     */
    private List<String> mCcEmails;

    /**
     * Array with e-mail addresses for blind carbon copy.
     */
    private List<String> mccEmails;

    /**
     * Constructors ================================================================================
     */

    /**
     * Creates a new instance of EmailIntent for the given <var>activity</var> context.
     * See {@link com.wit.android.support.content.intent.BaseIntent#BaseIntent(android.app.Activity)}
     * for additional info.
     */
    public EmailIntent(@NonNull Activity activity) {
        super(activity);
    }

    /**
     * Creates a new instance of EmailIntent for the given <var>fragment</var> context.
     * See {@link com.wit.android.support.content.intent.BaseIntent#BaseIntent(android.support.v4.app.Fragment)}
     * for additional info.
     */
    public EmailIntent(@NonNull Fragment fragment) {
        super(fragment);
    }

    /**
     * Methods =====================================================================================
     */

    /**
     * Public --------------------------------------------------------------------------------------
     */

    /**
     */
    @Nullable
    @Override
    public Intent buildIntent() {
        if (mEmails == null || mEmails.size() == 0) {
            Log.e(TAG, "Can not create an EMAIL intent. No e-mail address/-es specified.");
            return null;
        }
        /**
         * Build the intent.
         */
        final Intent intent = new Intent(Intent.ACTION_SENDTO, createEmailUri(mEmails));
        intent.putExtra(Intent.EXTRA_SUBJECT, mSubject);
        intent.putExtra(Intent.EXTRA_TEXT, mMessage);
        if (mCcEmails != null) {
            intent.putExtra(Intent.EXTRA_CC, mCcEmails.toArray());
        }
        if (mccEmails != null) {
            intent.putExtra(Intent.EXTRA_BCC, mccEmails.toArray());
        }
        return intent;
    }

    /**
     * Getters + Setters ---------------------------------------------------------------------------
     */

    /**
     * Same as {@link #to(String)}, where e-mail address will be obtain from the current context wrapper
     * (activity/fragment).
     *
     * @param resId Resource id of the desired e-mail address placed within an application resources.
     */
    public EmailIntent to(@StringRes int resId) {
        return to(obtainString(resId));
    }

    /**
     * Appends the given <var>address</var> to the current <b>primary</b> e-mail addresses which are used as
     * addresses to that should be e-mail message send.
     * <p>
     * <b>Note</b>, that only valid e-mail address will be added.
     *
     * @param address E-mail address to add.
     * @return This intent builder to allow methods chaining.
     * @see #to(String...)
     * @see #getEmailAddresses()
     */
    public EmailIntent to(@NonNull String address) {
        this.mEmails = appendEmailAddress(mEmails, address);
        return this;
    }

    /**
     * Appends the given set of <var>addresses</var> to the current <b>primary</b> e-mail addresses which
     * are used as addresses to that should be e-mail message send.
     * <p>
     * <b>Note</b>, that only valid e-mail addresses will be added.
     *
     * @param addresses Set of e-mail addresses to add.
     * @return This intent builder to allow methods chaining.
     * @see #getEmailAddresses()
     */
    public EmailIntent to(@NonNull String... addresses) {
        this.mEmails = appendEmailAddresses(mEmails, addresses);
        return this;
    }

    /**
     * Returns array with valid e-mail addresses.
     *
     * @return The array with the current <b>primary</b> e-mail addresses.
     * @see #to(int)
     * @see #to(String)
     * @see #to(String...)
     */
    @Nullable
    public List<String> getEmailAddresses() {
        return mEmails;
    }

    /**
     * Same as {@link #cc(String)}, where e-mail address will be obtain from the current context wrapper
     * (activity/fragment).
     *
     * @param resId Resource id of the desired e-mail address to add into <b>carbon copy</b> section.
     */
    public EmailIntent cc(@StringRes int resId) {
        return cc(obtainString(resId));
    }

    /**
     * Appends the given <var>address</var> to the current <b>carbon copy</b> e-mail addresses.
     * See {@link android.content.Intent#EXTRA_CC} for more info.
     * <p>
     * <b>Note</b>, that only valid e-mail address will be added.
     *
     * @param address E-mail address to add into <b>carbon copy</b> section.
     * @return This intent builder to allow methods chaining.
     * @see #cc(String...)
     * @see #getCcEmailAddresses()
     */
    public EmailIntent cc(@NonNull String address) {
        this.mCcEmails = appendEmailAddress(mCcEmails, address);
        return this;
    }

    /**
     * Appends the given set of <var>addresses</var> to the current <b>carbon copy</b> e-mail addresses.
     * See {@link android.content.Intent#EXTRA_CC} for more info.
     * <p>
     * <b>Note</b>, that only valid e-mail addresses will be added.
     *
     * @param addresses Set of e-mail addresses to add into <b>carbon copy</b> section.
     * @return This intent builder to allow methods chaining.
     * @see #getCcEmailAddresses()
     */
    public EmailIntent cc(@NonNull String... addresses) {
        this.mCcEmails = appendEmailAddresses(mCcEmails, addresses);
        return this;
    }

    /**
     * Returns array with valid e-mail addresses.
     *
     * @return The array with the current <b>carbon copy</b> e-mail addresses.
     * @see #cc(String)
     * @see #cc(String...)
     */
    @Nullable
    public List<String> getCcEmailAddresses() {
        return mCcEmails;
    }

    /**
     * Same as {@link #bcc(String)}, where e-mail address will be obtain from the current context wrapper
     * (activity/fragment).
     *
     * @param resId Resource id of the desired e-mail address to add into <b>blind carbon copy</b> section.
     */
    public EmailIntent bcc(@StringRes int resId) {
        return bcc(obtainString(resId));
    }

    /**
     * Appends the given <var>address</var> to the current <b>blind carbon copy</b> e-mail addresses.
     * See {@link android.content.Intent#EXTRA_BCC} for more info.
     * <p>
     * <b>Note</b>, that only valid e-mail address will be added.
     *
     * @param address E-mail address to add into <b>blind carbon copy</b> section.
     * @return This intent builder to allow methods chaining.
     * @see #cc(String...)
     * @see #getCcEmailAddresses()
     */
    public EmailIntent bcc(@NonNull String address) {
        this.mccEmails = appendEmailAddress(mccEmails, address);
        return this;
    }

    /**
     * Appends the given set of <var>addresses</var> to the current <b>blind carbon copy</b> e-mail
     * addresses. See {@link android.content.Intent#EXTRA_BCC} for more info.
     * <p>
     * <b>Note</b>, that only valid e-mail addresses will be added.
     *
     * @param addresses Set of e-mail addresses to add into <b>blind carbon copy</b> section.
     * @return This intent builder to allow methods chaining.
     * @see #getCcEmailAddresses()
     */
    public EmailIntent bcc(@NonNull String... addresses) {
        this.mccEmails = appendEmailAddresses(mccEmails, addresses);
        return this;
    }

    /**
     * Returns array with valid e-mail addresses.
     *
     * @return The array with the current <b>blind carbon copy</b> e-mail addresses.
     * @see #cc(String)
     * @see #cc(String...)
     */
    @Nullable
    public List<String> getBccEmailAddresses() {
        return mccEmails;
    }

    /**
     * Same as {@link #subject(CharSequence)}, where text will be obtained from the current context
     * wrapper (activity/fragment).
     *
     * @param resId Resource id of the desired subject text placed within an application resources.
     */
    public EmailIntent subject(@StringRes int resId) {
        return subject(obtainText(resId));
    }

    /**
     * Set the subject for e-mail to send. See {@link android.content.Intent#EXTRA_SUBJECT} for
     * more info.
     *
     * @param subject The desired subject text.
     * @return This intent builder to allow methods chaining.
     * @see #getSubject()
     */
    public EmailIntent subject(@NonNull CharSequence subject) {
        this.mSubject = subject;
        return this;
    }

    /**
     * Returns subject for e-mail to send.
     *
     * @return Subject of e-mail.
     * @see #subject(CharSequence)
     */
    @Nullable
    public CharSequence getSubject() {
        return mSubject;
    }

    /**
     * Same as {@link #message(CharSequence)}, where text will be obtained from the current context
     * wrapper (activity/fragment).
     *
     * @param resId Resource id of the desired e-mail message placed within an application resources.
     */
    public EmailIntent message(@StringRes int resId) {
        return message(obtainText(resId));
    }

    /**
     * Sets the message for e-mail to send.
     *
     * @param message The desired message text.
     * @return This intent builder to allow methods chaining.
     * @see #getMessage()
     */
    public EmailIntent message(@NonNull CharSequence message) {
        this.mMessage = message;
        return this;
    }

    /**
     * Returns message for e-mail to send
     *
     * @return Message of e-mail.
     * @see #message(CharSequence)
     */
    @Nullable
    public CharSequence getMessage() {
        return mMessage;
    }

    /**
     * Protected -----------------------------------------------------------------------------------
     */

    /**
     */
    @Override
    protected boolean onStart(@NonNull Intent intent) {
        startActivity(Intent.createChooser(intent, mDialogTitle));
        return true;
    }

    /**
     * Creates the URI specific for the {@link android.content.Intent#ACTION_SENDTO} intent action from
     * the given array of e-mails.
     *
     * @param emails Array with e-mail addresses.
     * @return Parsed URI.
     */
    @NonNull
    protected Uri createEmailUri(@NonNull List<String> emails) {
        final StringBuilder data = new StringBuilder(SCHEME);
        final int n = emails.size();

        for (int i = 0; i < n; i++) {
            data.append(emails.get(i));
            if (i < (n - 1)) {
                data.append(",");
            }
        }
        // Remove last comma and create uri.
        return Uri.parse(data.toString());
    }

    /**
     * Private -------------------------------------------------------------------------------------
     */

    /**
     * Appends the given <var>addresses</var> into the given <var>list</var>.
     *
     * @param list      An instance of list into which append addresses.
     * @param addresses Addresses to append.
     * @return If <var>list</var> is {@code null}, new instance of ArrayList with added addresses,
     * otherwise, same instance with appended addresses.
     */
    private List<String> appendEmailAddresses(List<String> list, String... addresses) {
        if (addresses.length > 0) {
            for (String address : addresses) {
                list = this.appendEmailAddress(list, address);
            }
        }
        return list;
    }

    /**
     * Appends the given <var>address</var> into the given <var>list</var>.
     *
     * @param list    An instance of list into which append address.
     * @param address Address to append.
     * @return If <var>list</var> is {@code null}, new instance of ArrayList with added address,
     * otherwise, same instance with appended address.
     */
    private List<String> appendEmailAddress(List<String> list, String address) {
        if (!EMAIL_MATCHER.reset(address).matches()) {
            Log.e(TAG, "Invalid e-mail address('" + address + "')");
            return list;
        }
        if (list == null) {
            list = new ArrayList<>();
        }
        list.add(address);
        return list;
    }

    /**
     * Inner classes ===============================================================================
     */
}