I am attempting to use an Intent Service to run in the background to send email with fairly large (1-2mb) image attachments. I am a beginner, and have learned everything so far by researching on the web (so you may see some similar code).
What happens is that when I send the first email, everything works fine. However when I attempt to send another while the first is still processing, the first is dropped and the second goes through fine. It will always send the most recent of the queued intents and skip the ones before it.
From the research I have done, IntentService is supposed to queue the intents passed to it, and execute them sequentially in order. This question: IntentService : How to enqueue correctly? is similar, but I don't think it applies to my situation exactly.
I am sure I am missing something dumb =(
This is the onActivityResult where I start the service:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "Entered onActivityResult");
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Log.i(TAG, "onActivityResult Canceled");
Toast toast = Toast.makeText(this,"Camera Canceled", 10000);
toast.show();
return;
}
if ((requestCode == CAMERA_PIC_REQUEST) && (resultCode == Activity.RESULT_OK)) {
Log.i(TAG, "onActivityResult Result OK");
String filePath = getOutputPath();
String order = getOrder();
Log.i(TAG, "Sending From: " + filePath);
Intent sendIntent = new Intent(this, MailIntentService.class);
sendIntent.putExtra(MailIntentService.IN_SUBJECT, order);
sendIntent.putExtra(MailIntentService.IN_PATH, filePath);
startService(sendIntent);
Toast.makeText(this, "Image Upload Started. Check Notification Bar for Status.", Toast.LENGTH_LONG).show();
}
}
This is the entire IntentService:
public class MailIntentService extends IntentService {
//These set the parameters for the Email
public static final String destEmail = "hidden";
public static final String sendEmail = "hidden";
public static final String sendPass = "hidden";
public static final String body = "GrowerLive image upload request.";
public static final String IN_SUBJECT = "insub";
public static final String IN_PATH = "inpath";
//This is the standard tag for class name
private static final String TAG = MailIntentService.class.getSimpleName();
//These set up the parameters for notifications
private NotificationManager mNotificationManager;
private Notification notifyDetails;
private int NOTIFICATION_ID;
private CharSequence contentTitle = "Bethel Upload";
private CharSequence contentText = "Image Uploading...";
private String contentTicker = "Upload Started...";
public void onCreate() {
super.onCreate();
Log.i(TAG, "MailIntentService Created");
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notifyDetails = new Notification(R.drawable.ic_launcher, contentTicker, System.currentTimeMillis());
}
public void onDestroy() {
super.onDestroy();
File dir = new File(Environment.getExternalStorageDirectory() + "/BethelUpload");
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
new File(dir, children[i]).delete();
}
}
Log.i(TAG, "MailIntentService Destroyed");
}
public MailIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
Context context = getApplicationContext();
Intent notifyIntent = new Intent(BethelUploadActivity.class.getSimpleName());
PendingIntent intentP = PendingIntent.getActivity(MailIntentService.this, 0, notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
notifyDetails.setLatestEventInfo(context, contentTitle, contentText, intentP);
try {
String subject = intent.getStringExtra(IN_SUBJECT);
String path = intent.getStringExtra(IN_PATH);
Log.i(TAG, "Sending Mail...");
Log.i(TAG, "Subject: " + subject);
Log.i(TAG, "Attachment Path: " + path);
mNotificationManager.notify(NOTIFICATION_ID, notifyDetails);
GMailSender sender = new GMailSender(sendEmail, sendPass);
sender.sendMail(subject, body, sendEmail, destEmail, path);
Log.i(TAG, "Mail Sent!");
contentText = "Image Uploaded Successfully";
contentTicker = "Upload Successful";
notifyDetails.setLatestEventInfo(context, contentTitle, contentText, intentP);
mNotificationManager.notify(NOTIFICATION_ID, notifyDetails);
}
catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
}
}
This is the GMailSender I use from another example here: Sending Email in Android using JavaMail API without using the default/built-in app
public class GMailSender extends javax.mail.Authenticator {
private String mailhost = "smtp.gmail.com";
private String user;
private String password;
private Session session;
static {
Security.addProvider(new com.provider.JSSEProvider());
}
public GMailSender(String user, String password) {
this.user = user;
this.password = password;
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", mailhost);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.quitwait", "false");
session = Session.getDefaultInstance(props, this);
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
public synchronized void sendMail(String subject, String body, String sender, String recipients, String fileAttachment) throws Exception {
try{
MimeMessage message = new MimeMessage(session);
message.setSender(new InternetAddress(sender));
message.setSubject(subject);
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(fileAttachment);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName("SodPhoto.jpg");
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
if (recipients.indexOf(',') > 0)
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
else
message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));
Transport.send(message);
}catch(Exception e){
}
}
public class ByteArrayDataSource implements DataSource {
private byte[] data;
private String type;
public ByteArrayDataSource(byte[] data, String type) {
super();
this.data = data;
this.type = type;
}
public ByteArrayDataSource(byte[] data) {
super();
this.data = data;
}
public void setType(String type) {
this.type = type;
}
public String getContentType() {
if (type == null)
return "application/octet-stream";
else
return type;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(data);
}
public String getName() {
return "ByteArrayDataSource";
}
public OutputStream getOutputStream() throws IOException {
throw new IOException("Not Supported");
}
}
}
I know this is a huge amount of code / wall of text, but I figured I would rather give you too much information than too little. I really appreciate your time!