Android:IntentService无法正常排队

时间:2012-01-04 21:39:15

标签: android queue android-intent android-service intentservice

我正在尝试使用Intent Service在后台运行以发送带有相当大(1-2mb)图像附件的电子邮件。我是初学者,到目前为止通过网络研究已经学到了所有东西(所以你可能会看到一些类似的代码)。

当我发送第一封电子邮件时,一切正常。然而,当我在第一个仍在处理时尝试发送另一个时,第一个被丢弃而第二个被罚款。它将始终发送最新的排队意图并跳过之前的意图。

根据我所做的研究,IntentService应该对传递给它的意图进行排队,并按顺序依次执行它们。这个问题:IntentService : How to enqueue correctly?类似,但我认为它并不完全适用于我的情况。

我确信我遗失了一些哑巴=(

这是我启动服务的onActivityResult:

    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();
    }
}

这是整个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);    
    }       
}
}

这是我在另一个例子中使用的GMailSender: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");
    }
}
}

我知道这是一个庞大的代码/文本墙,但我想我宁愿给你太多的信息而不是太少。我非常感谢你的时间!

3 个答案:

答案 0 :(得分:1)

我认为这将是解决方案......

     GMailSender sender = new GMailSender(sendEmail, sendPass); 
         SystemClock.sleep(30000);
    sender.sendMail(subject, body, sendEmail, destEmail, path);

这使得您的第一封邮件在30秒内从当前系统时间延迟发送,第二封邮件也以这种方式发送......

答案 1 :(得分:1)

在确定使用SystemClock.sleep(30000)(感谢下面的DineshKumar)将解决我的问题后,我做了一些研究,发现网络调用并不总是阻止IntentServiceSystemClock.sleep(30000)会阻止IntentService,但即使它不需要(不是最佳),它也会等待30秒。

然后我找到了一种方法来检查我的GMailSender类是否正在处理:

private boolean isSending() {
        ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> runningProcInfo = manager.getRunningAppProcesses();
        for(int i = 0; i < runningProcInfo.size(); i++) {
        if(runningProcInfo.get(i).processName.equals("com.bethelfarms.bethelupload.GMailSender")) {
            Log.i(TAG, "isSending is true");
            return true;
        }
    }
    Log.i(TAG,"isSending is false");
    return false;
}

然后我在我的while中放置了IntentService循环来阻止代码,直到它看到GMailSender已完成处理:

        GMailSender sender = new GMailSender(sendEmail, sendPass);  
        //Blocking action to wait for previous message to send
        sent = isSending();
        while(sent==true) {
            SystemClock.sleep(1000);
            sent = isSending();
        }
        sender.sendMail(subject, body, sendEmail, destEmail, path); 

答案 2 :(得分:0)

在pendingIntent..it中使用请求代码是你的代码

   PendingIntent intentP = PendingIntent.getActivity(MailIntentService.this, 0,     notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);

看看为什么你的第一封邮件没有被发送但是最后一封邮件发送问题的是在待处理的意图中使用请求代码,即为每个未决的意图创建一个单独的id ..我将显示一个简单的例子..

    int COUNT=Integer.parseInt(some_txt.getText().toString());

    if(COUNT==1)  
     { 
        PendingIntent intentP = PendingIntent.getService(MailIntentService.this, COUNT,     notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
     }
   else if(COUNT==2)
   {
       PendingIntent intentP = PendingIntent.getActivity(MailIntentService.this, COUNT,     notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
    }
  else if(COUNT==3)
  {
     PendingIntent intentP = PendingIntent.getActivity(MailIntentService.this, COUNT,     notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
   }

查看而不是使用startService()直接尝试使用AlarmManager pendingIntent,以便在指定时间发送邮件 我希望这会对你有所帮助..