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

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 04 апр 2013, 16:07

Примеров отправки 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.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

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

Сообщение KamiSempai » 05 апр 2013, 16:11

В проблеме не разбирался, но у меня возник один вопрос.
Есть возможность поднять сервер (например PHP) и слать изображения на него через POST запросы?
Сервер сможет все аккуратно разложить по папочкам с указанием времени и даты.
Я уверен на 100%, что так еще быстрее будет. И не нужно будет копаться в куче писем с вложениями.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 05 апр 2013, 18:43

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

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 07 апр 2013, 23:02

Что-то нет ответа. :(
Что же это за Lcom в
W/dalvikvm(214): Unable to resolve superclass of Lcom/habra/example/com/MailSenderClass;
?

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

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

Сообщение Mikhail_dev » 07 апр 2013, 23:18

Во-первых
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.
Ответ нарыл тут

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 07 апр 2013, 23:34

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 спасибо огромное, пошёл читать статью.

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

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

Сообщение rezak90 » 07 апр 2013, 23:37

через двоеточию значит что это строка в файле
R.id.team
Политика на форуме запрещена

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

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

Сообщение Mikhail_dev » 07 апр 2013, 23:50

Сбрось дополнительные библиотеки в папку 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)

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

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

Сообщение Mikhail_dev » 07 апр 2013, 23:51

через двоеточию значит что это строка в файле
А есть другие варианты?

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

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

Сообщение rezak90 » 08 апр 2013, 00:14

А есть другие варианты?
а они нужны? :D
R.id.team
Политика на форуме запрещена

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 08 апр 2013, 00:17

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.)

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 08 апр 2013, 00:24

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

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

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

Сообщение Mikhail_dev » 08 апр 2013, 10:10

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

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 13 апр 2013, 20:38

В этом примере адрес получателя (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!
Подскажите, плиз, что не так?

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

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

Сообщение neoksi » 13 апр 2013, 21:22

Разрешение доступа к интернету в манифесте прописал?

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 13 апр 2013, 21:34

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

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 13 апр 2013, 21:41

Подозрения падают на переменные to и pass в

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

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

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

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

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

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

Сообщение rezak90 » 13 апр 2013, 22:05

Debug? Не, не слышал :?
R.id.team
Политика на форуме запрещена

=bor=
Сообщения: 267
Зарегистрирован: 21 мар 2013, 12:26

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

Сообщение =bor= » 13 апр 2013, 22:28

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

Anastasi
Сообщения: 10
Зарегистрирован: 09 апр 2013, 10:08

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

Сообщение Anastasi » 21 май 2013, 14:55

Пожалуйста, подскажите в чем ошибка. Скачала этот же исходник, библиотеки подключила правильно, но у меня отправка не работает. Вот такой вот лог:
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]
Последний раз редактировалось Anastasi 21 май 2013, 15:20, всего редактировалось 1 раз.

Ответить