kurukuru-papaのブログ

主に、ソフトウェア開発に関連したメモを書き溜めたいと思います。

メール送信サンプル

Androidで、メール送信アプリを呼び出して、メール送信するサンプルを作成してみました。

メール送信には、次の2つの方法があるようですが、今回のサンプルは1です。
1.メールアプリを起動して、メール送信。
2.Google提供のライブラリを使用して、メール送信。

作成したサンプルの画面イメージは、次です。宛先、件名、内容、添付ファイルを指定して、送信ボタンをクリックすると、メールアプリを起動して、メール送信を行います。宛先は、未設定でも、カンマで区切って複数指定することも出来ます。添付ファイルは、なし または1つのみです。
注意:本体内ファイルを添付することも出来るようにしましたが機能しません。起動したメールアプリには添付ファイルが付くのですが、メールを受信してみると添付ファイルがなくなっていました。

各種ソース

レイアウト用XMLファイル(mail_send_activity.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="wrap_content" android:text="宛先"
		android:layout_height="wrap_content"></TextView>
	<EditText android:id="@+id/mail_send_to_edit_text"
		android:layout_width="fill_parent" android:layout_height="wrap_content"></EditText>

	<TextView android:layout_width="wrap_content" android:text="件名"
		android:layout_height="wrap_content"></TextView>
	<EditText android:id="@+id/mail_send_subject_edit_text"
		android:layout_width="fill_parent" android:layout_height="wrap_content"></EditText>

	<TextView android:layout_width="wrap_content" android:text="内容"
		android:layout_height="wrap_content"></TextView>
	<EditText android:id="@+id/mail_send_content_edit_text"
		android:layout_width="fill_parent" android:layout_height="wrap_content"></EditText>

	<TextView android:layout_width="wrap_content" android:text="添付ファイル"
		android:layout_height="wrap_content"></TextView>
	<RadioGroup android:id="@+id/mail_send_file_radio_group"
		android:layout_width="fill_parent" android:layout_height="wrap_content">
		<RadioButton android:id="@+id/mail_send_nofile_radio_button"
			android:text="なし" android:layout_width="wrap_content"
			android:layout_height="wrap_content" android:checked="true"></RadioButton>
		<RadioButton android:id="@+id/mail_send_file_radio_button"
			android:text="本体内ファイル" android:layout_width="wrap_content"
			android:layout_height="wrap_content"></RadioButton>
		<RadioButton android:id="@+id/mail_send_sdcard_file_radio_button"
			android:text="SDカード内ファイル" android:layout_width="wrap_content"
			android:layout_height="wrap_content"></RadioButton>
	</RadioGroup>

	<Button android:id="@+id/mail_send_button" android:text="送信"
		android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>

</LinearLayout>

Activityクラスです。

public class MailSendActivity extends Activity implements OnClickListener {
	private Button button;
	private EditText toEditText;
	private EditText subjectEditText;
	private EditText contentEditText;
	private File file;
	private File sdcardFile;
	private RadioGroup fileRadioGroup;

	/*
	 * (非 Javadoc)
	 *
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		LogUtil.called();

		// レイアウト設定
		setContentView(R.layout.mail_send_activity);

		// ビューオブジェクト取得
		button = (Button) findViewById(R.id.mail_send_button);
		toEditText = (EditText) findViewById(R.id.mail_send_to_edit_text);
		subjectEditText = (EditText) findViewById(R.id.mail_send_subject_edit_text);
		contentEditText = (EditText) findViewById(R.id.mail_send_content_edit_text);
		fileRadioGroup = (RadioGroup) findViewById(R.id.mail_send_file_radio_group);

		// ビューオブジェクト設定
		button.setOnClickListener(this);
		toEditText.setText("");
		subjectEditText.setText(getString(R.string.app_name));
		contentEditText.setText("メール送信テストです。\n届きましたか?");

		// 添付ファイル作成(本体内ストレージ)
		// ※本体内の記憶領域に保存したファイルは、メール添付できない(エラーにならないが
		//  受信したメールに添付ファイルが付いていない)ようですが、動作確認のため記述。
		String name = getClass().getSimpleName() + ".txt";
		try {
			ActivityUtil.saveFile(this, name, Context.MODE_WORLD_READABLE,
					"test\naaa\nbbb\nccc");
			file = ActivityUtil.getFile(this, name);
		} catch (IOException e) {
			ActivityUtil.showDialog(this, "エラー", e.toString());
		}

		// 添付ファイル作成(外部ストレージ)
		try {
			ActivityUtil.saveFileOnExternalStorage(this, name,
					"test\naaa\nbbb\nccc");
			sdcardFile = ActivityUtil.getFileOnExternalStorage(this, name);
		} catch (IOException e) {
			ActivityUtil.showDialog(this, "エラー", e.toString());
		}
	}

	@Override
	public void onClick(View view) {
		if (view == button) {
			onSendButtonClick();
		}
	}

	private void onSendButtonClick() {
		String[] toArr = toEditText.getText().toString().split(",");
		String subject = subjectEditText.getText().toString();
		String content = contentEditText.getText().toString();
		int fileCheckedId = fileRadioGroup.getCheckedRadioButtonId();
		File f = null;

		switch (fileCheckedId) {
		case R.id.mail_send_file_radio_button:
			f = file;
			break;
		case R.id.mail_send_sdcard_file_radio_button:
			f = sdcardFile;
			break;
		}
		if (f != null) {
			content += "\n\n添付ファイル名:" + f.getAbsolutePath() + "\nサイズ:"
					+ f.length();
		}

		// メール送信アプリ起動
		ActivityUtil.startActivityForMailSend(this, toArr, subject, content, f,
				"text/plain");
	}
}

メール送信部分などのメソッドです。

public class ActivityUtil {
	/**
	 * メールアプリを起動してメール送信
	 *
	 * @param activity
	 * @param toArr
	 * @param subject
	 * @param text
	 * @param file
	 *            複数ファイルを添付したいときはZIPファイルに圧縮アーカイブして指定する。
	 * @param type
	 *            添付ファイルのタイプ。"text/plain", "image/jpeg"など。
	 */
	public static void startActivityForMailSend(Activity activity,
			String[] toArr, String subject, String text, File file, String type) {
		Intent intent = new Intent();
		if (subject != null) {
			intent.putExtra(Intent.EXTRA_SUBJECT, subject);
		}
		if (text != null) {
			intent.putExtra(Intent.EXTRA_TEXT, text);
		}
		if (file == null) {
			// 標準メールアプリ
			intent.setAction(Intent.ACTION_SENDTO);
			// 宛先はカンマ区切りの文字列として渡す
			StringBuilder sb = new StringBuilder();
			for (String to : toArr) {
				// 最後に不要なカンマが付いていても問題ない
				sb.append(to + ",");
			}
			intent.setData(Uri.parse("mailto:" + sb.toString()));

			// 標準メールアプリ呼び出し
			activity.startActivity(intent);
		} else {
			// 標準メールアプリでは、添付ファイルをつけて、直接呼び出すことが出来ないため、
			// 添付ファイルが存在する場合は、アプリを選択して送信。
			intent.setAction(Intent.ACTION_SEND);
			// 宛先
			if (toArr != null && toArr.length > 0) {
				intent.putExtra(Intent.EXTRA_EMAIL, toArr);
			}
			// 添付ファイル
			// 複数ファイルのまま添付する方法は不明。配列で渡すと例外が発生する。
			intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"
					+ file.getAbsolutePath()));
			intent.setType(type);

			// アプリ呼び出し
			activity.startActivity(Intent.createChooser(intent,
					"メールアプリを選択してください"));
		}
	}

	/**
	 * 外部ストレージにファイル保存
	 *
	 * @param context
	 * @param name
	 *            ファイル名。ディレクトリ区切り含めること可能。
	 * @param data
	 * @throws IOException
	 */
	public static void saveFileOnExternalStorage(Context context, String name,
			String data) throws IOException {
		// 外部ストレージ内の保存先フォルダ
		// 一般的にフォルダ名にはパッケージ名を使用するらしい
		File dir = new File(Environment.getExternalStorageDirectory(), context
				.getPackageName());

		// 始めてファイル保存する場合を考慮してフォルダ作成する
		dir.mkdirs();

		// ファイル名
		File file = new File(dir.getAbsolutePath(), name);

		// ファイル書き込み
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(file);
			fos.write(data.getBytes());
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					LogUtil.e("ファイルクローズ失敗", e);
				}
			}
		}

		LogUtil.i("File saved: " + file.getAbsolutePath());
	}

動作確認環境