Страница 1 из 4

Отправка Email без Intent

Добавлено: 04 апр 2013, 16:07
=bor=
Примеров отправки email из приложения в Инете много, но большинство из них используют Intent и Chooser.
Это предполагает реакцию юзера - выбрать приложение и нажать на кнопку отправки.
Как быть, если мы реализуем приложение, предполагающее автоматическую отправку данных без участия пользователя?
Сразу хочу оговориться, что это не шпионская утилита, а приложение для метеорологов, отсылающее с заданным интервалом времени фото облачности, и потом эти фото используются для прогнозирования погоды.
Встаёт вопрос, как отсылать? Можно использовать внешний сервер, принимающий данные, можно email, можно mms.
Пытаясь выяснить, что лучше, задал вопрос во Флудильне: Что быстрее - email или mms? Пока вразумительного ответа нет.
На Хабре нашёл интересную статью: Отправка E-Mail средствами Android. В Части 2 там описан способ отправки email, не требующий от пользователя настроенного клиента.
Исходный код приложения там приложен, потому можно быстро проверить его работоспособность.
Для работы используется дополнительные библиотеки javamail-android.
Качаем их, и встраиваем в проект: Контекстное меню проекта > «Build Path» > «Add External Archives...» > «Наши файлы additional, mail, activation»
У меня на эмуляторе не заработало вот с таким сообщением:
Изображение
и с такими логами:

Код: Выделить всё

04-04 12:34:50.364: W/dalvikvm(214): Unable to resolve superclass of Lcom/habra/example/com/MailSenderClass; (86)
04-04 12:34:50.374: W/dalvikvm(214): Link of class 'Lcom/habra/example/com/MailSenderClass;' failed
04-04 12:34:50.374: E/dalvikvm(214): Could not find class 'com.habra.example.com.MailSenderClass', referenced from method com.habra.example.com.ExtendedMail$sender_mail_async.doInBackground
04-04 12:34:50.384: W/dalvikvm(214): VFY: unable to resolve new-instance 46 (Lcom/habra/example/com/MailSenderClass;) in Lcom/habra/example/com/ExtendedMail$sender_mail_async;
04-04 12:34:50.394: D/dalvikvm(214): VFY: replacing opcode 0x22 at 0x003a
04-04 12:34:50.394: D/dalvikvm(214): Making a copy of Lcom/habra/example/com/ExtendedMail$sender_mail_async;.doInBackground code (248 bytes)
04-04 12:34:50.554: W/dalvikvm(214): threadid=17: thread exiting with uncaught exception (group=0x4001b188)
04-04 12:34:50.554: E/AndroidRuntime(214): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
04-04 12:34:50.624: E/AndroidRuntime(214): java.lang.RuntimeException: An error occured while executing doInBackground()
04-04 12:34:50.624: E/AndroidRuntime(214): 	at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at java.lang.Thread.run(Thread.java:1096)
04-04 12:34:50.624: E/AndroidRuntime(214): Caused by: java.lang.NoClassDefFoundError: com.habra.example.com.MailSenderClass
04-04 12:34:50.624: E/AndroidRuntime(214): 	at com.habra.example.com.ExtendedMail$sender_mail_async.doInBackground(ExtendedMail.java:94)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at com.habra.example.com.ExtendedMail$sender_mail_async.doInBackground(ExtendedMail.java:1)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-04 12:34:50.624: E/AndroidRuntime(214): 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-04 12:34:50.624: E/AndroidRuntime(214): 	... 4 more
04-04 12:34:51.044: I/dalvikvm(214): threadid=7: reacting to signal 3
04-04 12:34:51.114: I/dalvikvm(214): Wrote stack trace to '/data/anr/traces.txt'
04-04 12:39:51.174: I/Process(214): Sending signal. PID: 214 SIG: 9
Вот это из лога

Код: Выделить всё

Unable to resolve superclass of Lcom/habra/example/com/MailSenderClass; (86)
означает, что ошибка в 86й строке кода MailSenderClass.java, так? Там завершение if, проверяющего непустое имя вложения. Может, не хватает else? Я никакого видео не вкладываю.

Прошу совета, как заставить это всё заработать.

PS. Не забудьте в

Код: Выделить всё

MailSenderClass sender = new MailSenderClass("ваш_логин@gmail.com", "password");
подставить параметры ящика на Gmail.com.

Re: Отправка Email без Intent

Добавлено: 05 апр 2013, 16:11
KamiSempai
В проблеме не разбирался, но у меня возник один вопрос.
Есть возможность поднять сервер (например PHP) и слать изображения на него через POST запросы?
Сервер сможет все аккуратно разложить по папочкам с указанием времени и даты.
Я уверен на 100%, что так еще быстрее будет. И не нужно будет копаться в куче писем с вложениями.

Re: Отправка Email без Intent

Добавлено: 05 апр 2013, 18:43
=bor=
KamiSempai писал(а):Есть возможность поднять сервер (например PHP) и слать изображения на него через POST запросы?
Конечно, можно и так, но тогда кому-то нужно держать сервер и обрабатывать эти запросы, но зачем?
Ведь в каждом телефоне эта функция уже есть, я про приём email или mms.

Re: Отправка Email без Intent

Добавлено: 07 апр 2013, 23:02
=bor=
Что-то нет ответа. :(
Что же это за Lcom в
W/dalvikvm(214): Unable to resolve superclass of Lcom/habra/example/com/MailSenderClass;
?

Re: Отправка Email без Intent

Добавлено: 07 апр 2013, 23:18
Mikhail_dev
Во-первых
Unable to resolve superclass of Lcom/habra/example/com/MailSenderClass; (86)
Не означает что ошибка в 86 строке. В стектрейсе так пишутся строки с ошибками
04-04 12:34:50.624: E/AndroidRuntime(214): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
Ну а во-вторых ошибка наверное из-за того, что либа, что ты используешь, лежит не в папке libs.
Ответ нарыл тут

Re: Отправка Email без Intent

Добавлено: 07 апр 2013, 23:34
=bor=
no-- писал(а):Во-первых
Unable to resolve superclass of Lcom/habra/example/com/MailSenderClass; (86)
Не означает что ошибка в 86 строке. В стектрейсе так пишутся строки с ошибками
04-04 12:34:50.624: E/AndroidRuntime(214): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
Да, я уже понял, что с 86 лоханулся, когда во многочисленных попытках запуска и анализа логов было уже не 86, а 588 и т.п. :)
Обратил внимание, что иногда цифры в скобках, иногда через двоеточие, что это значит - непонятно. В Справке по Эклипсу ничего не нашёл про анализ логов, где бы почитать :?:
no-- писал(а):Ну а во-вторых ошибка наверное из-за того, что либа, что ты используешь, лежит не в папке libs.
Ответ нарыл тут
За libs спасибо огромное, пошёл читать статью.

Re: Отправка Email без Intent

Добавлено: 07 апр 2013, 23:37
rezak90
через двоеточию значит что это строка в файле

Re: Отправка Email без Intent

Добавлено: 07 апр 2013, 23:50
Mikhail_dev
Сбрось дополнительные библиотеки в папку libs в проекте, дальше обнови проект (правой стороной мыши по проекты>refresh) и попробуй запустить проект
Обратил внимание, что иногда цифры в скобках, иногда через двоеточие, что это значит - непонятно. В Справке по Эклипсу ничего не нашёл про анализ логов, где бы почитать
Ты про
04-04 12:34:50.624: E/AndroidRuntime(214)
? Если да, то скорее всего это внутренний номер ошибки в андроиде, где-то в его логах. Сама же строка пишется так
...(ThreadPoolExecutor.java:1068)
Стектрейс (лог) обычно идет с самого внутреннего вызова к самому высокому. Другими словами

Код: Выделить всё

class Test { 
1. public void methodOne() { 
2.  int a = 2/0;
3. }
4. 
5. public void methodTwo() { 
6.  methodeOne();
7. }
}
вот есть к примеру код. второй метод вызывает первый, в котором идет ошибка с делением на нуль. Стектрейс будет что-то типа
java.lang.ArithmeticException: divide by zero
04-04 12:34:50.624: E/AndroidRuntime(214): at название.пакета.Test.methodeOne (Test.java:2)
04-04 12:34:50.624: E/AndroidRuntime(214): at название.пакета.Test.methodeTwo(Test.java:6)

Re: Отправка Email без Intent

Добавлено: 07 апр 2013, 23:51
Mikhail_dev
через двоеточию значит что это строка в файле
А есть другие варианты?

Re: Отправка Email без Intent

Добавлено: 08 апр 2013, 00:14
rezak90
А есть другие варианты?
а они нужны? :D

Re: Отправка Email без Intent

Добавлено: 08 апр 2013, 00:17
=bor=
no-- писал(а):Ну а во-вторых ошибка наверное из-за того, что либа, что ты используешь, лежит не в папке libs.
Ответ нарыл тут
Супер! Заработало!!
Спасибо, no--.
Я тут Adding a library/JAR to an Eclipse Android project детальную инструкцию нарыл:
Here is the step-by-step:
1.Download the library to your host development system.
2.Create a new folder, libs, in your Eclipse/Android project.
3.Right-click libs and choose Import -> General -> File System, then Next, Browse in the filesystem to find the library's parent directory (i.e.: where you downloaded it to).
4.Click OK, then click the directory name (not the checkbox) in the left pane, then check the relevant JAR in the right pane. This puts the library into your project (physically).
5.Right-click on your project, choose Build Path -> Configure Build Path, then click the Libraries tab, then Add JARs..., navigate to your new JAR in the libs directory and add it. (This, incidentally, is the moment at which your new JAR is converted for use on Android.)

Re: Отправка Email без Intent

Добавлено: 08 апр 2013, 00:24
=bor=
no-- писал(а):Сбрось дополнительные библиотеки в папку libs в проекте, дальше обнови проект (правой стороной мыши по проекты>refresh) и попробуй запустить проект
У меня ж осталась старая ссыль на эти либы в References Libraries, а через Configure Build Path я их удалил. Возможно, их можно было и оставить, но я не хотел, чтоб в .apk было 2 копии либ.

Re: Отправка Email без Intent

Добавлено: 08 апр 2013, 10:10
Mikhail_dev
rezak90 писал(а):
А есть другие варианты?
а они нужны? :D
Ну это же ООП, тут всё классы и объекты. Класс по сути это файл. Я вот и подумал, может что еще есть =)

Re: Отправка Email без Intent

Добавлено: 13 апр 2013, 20:38
=bor=
В этом примере адрес получателя (bbb@yandex.ru), а также адрес отправителя (mypostmail@gmail.com) и пароль (password) задаются в коде:

Код: Выделить всё

@Override
protected Boolean doInBackground(Object... params) {
	try {
	title = ((EditText)findViewById(R.id.screen_sendnews_et_title)).getText().toString();
	text = ((EditText)findViewById(R.id.screen_sendnews_et_text)).getText().toString();
	from = "mypostmail@gmail.com";
	where = "bbb@yandex.ru";
MailSenderClass sender = new MailSenderClass("mypostmail@gmail.com", "password");
sender.sendMail(title, text, from, where, attach);
	} 
              catch (Exception e) {
	Toast.makeText(mainContext, "Ошибка отправки сообщения!", Toast.LENGTH_SHORT).show();
	}
	return false;
}
Чтобы можно было отправлять с любого Gmail-аккаунта на любой адрес, модифицируем.
Добавляем на extended_mail.xml ещё 3 EditText:

Код: Выделить всё

    <EditText
        android:id="@+id/editTextTo"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textEmailAddress"
        android:text="To" />

    <EditText
        android:id="@+id/editTextFrom"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textEmailAddress"
        android:text="Gmail adress" />

    <EditText
        android:id="@+id/editTextPass"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPassword"
        android:text="******" >
Изображение
Правим код ExtendedMail.java:

Код: Выделить всё

package com.example.habrahabr_mailapp;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class ExtendedMail extends Activity {

	int SELECTION = 3;
	
	Context mainContext;
	
	String title;
	String text;
	String to;
	String from;
	String pass;
	//String where;
	String attach;
	
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.extended_mail);
        
        mainContext = this;
        attach = "";
        
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        
        ((Button)findViewById(R.id.screen_sendnews_btn_selectVideo)).setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent i = new Intent(mainContext, ExtendedMailVideoSelect.class);
				startActivityForResult(i, SELECTION);
			}
		});
        
        ((Button)findViewById(R.id.screen_sendnews_btn_send)).setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				sender_mail_async async_sending = new sender_mail_async();
				async_sending.execute();
			}
		});
    }
    
    @Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (resultCode) {
            case 5:
            	((Button)findViewById(R.id.screen_sendnews_btn_selectVideo)).setText(data.getExtras().getString("video_path"));
            	attach = data.getExtras().getString("video_path");
            default:
                break;
        }
    }
    
    private class sender_mail_async extends AsyncTask<Object, String, Boolean> {
    	ProgressDialog WaitingDialog;

		@Override
		protected void onPreExecute() {
			WaitingDialog = ProgressDialog.show(ExtendedMail.this, "Отправка данных", "Отправляем сообщение...", true);
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			WaitingDialog.dismiss();
			Toast.makeText(mainContext, "Отправка завершена!!!", Toast.LENGTH_LONG).show();
			((Activity)mainContext).finish();
		}

		@Override
		protected Boolean doInBackground(Object... params) {

			try {
				title = ((EditText)findViewById(R.id.screen_sendnews_et_title)).getText().toString();
				text = ((EditText)findViewById(R.id.screen_sendnews_et_text)).getText().toString();
				from = ((EditText)findViewById(R.id.editTextFrom)).getText().toString();
				to = ((EditText)findViewById(R.id.editTextTo)).getText().toString();
				pass = ((EditText)findViewById(R.id.editTextPass)).getText().toString();
				
				//from = "mypostmail@gmail.com";
				//where = "bbb@yandex.ru";
				
                MailSenderClass sender = new MailSenderClass(to, pass);
                
                sender.sendMail(title, text, from, to, attach);
			} catch (Exception e) {
				Toast.makeText(mainContext, "Ошибка отправки сообщения!", Toast.LENGTH_SHORT).show();
			}
			
			return false;
		}
	}
}
Компилируем проект, загружаем .apk в эмулятор, заполняем адрес получателя, свой логин и пароль на Gmail.com и жмём на "Отправить". Получаем сообщение "Отправка завершена!!!", но... сообщение не приходит!!
В логе вот что:
04-13 17:31:49.378: E/sendMail(535): Ошибка отправки функцией sendMail!
Подскажите, плиз, что не так?

Re: Отправка Email без Intent

Добавлено: 13 апр 2013, 21:22
neoksi
Разрешение доступа к интернету в манифесте прописал?

Re: Отправка Email без Intent

Добавлено: 13 апр 2013, 21:34
=bor=
neoksi писал(а):Разрешение доступа к интернету в манифесте прописал?
Да. Этот код до модификации (ввода 3х EditText) исправно работал.

Re: Отправка Email без Intent

Добавлено: 13 апр 2013, 21:41
=bor=
Подозрения падают на переменные to и pass в

Код: Выделить всё

MailSenderClass sender = new MailSenderClass(to, pass);
Когда явно задавались:

Код: Выделить всё

MailSenderClass sender = new MailSenderClass("mypostmail@gmail.com", "password);
всё работало.
Как бы посмотреть, что считывается с соответствующих EditText и подставляется в MailSenderClass()?
Не соображу, как лог организовать. :(

Re: Отправка Email без Intent

Добавлено: 13 апр 2013, 22:05
rezak90
Debug? Не, не слышал :?

Re: Отправка Email без Intent

Добавлено: 13 апр 2013, 22:28
=bor=
rezak90 писал(а):Debug? Не, не слышал :?
:D
Уже разобрался, заработало.
Там не MailSenderClass(to, pass) должно быть, а MailSenderClass(from, pass).

Re: Отправка Email без Intent

Добавлено: 21 май 2013, 14:55
Anastasi
Пожалуйста, подскажите в чем ошибка. Скачала этот же исходник, библиотеки подключила правильно, но у меня отправка не работает. Вот такой вот лог:
05-21 12:16:08.705: I/exception(394): javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465;
05-21 12:16:08.705: I/exception(394): nested exception is:
05-21 12:16:08.705: I/exception(394): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
[/code]