我正在尝试使用在后台运行的 Intent 服务来发送带有相当大 (1-2mb) 图像附件的电子邮件。我是初学者,到目前为止,我已经通过网络研究了解了所有内容(因此您可能会看到一些类似的代码)。
发生的情况是,当我发送第一封电子邮件时,一切正常。但是,当我尝试在第一个仍在处理时发送另一个时,第一个被丢弃,第二个正常。它将始终发送最新的排队 Intent 并跳过它之前的 Intent 。
根据我所做的研究,IntentService 应该将传递给它的 Intent 排队,并按顺序依次执行它们。本题: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");
}
}
}
我知道这是大量的代码/文字墙,但我想我宁愿给你太多的信息也不愿给你太少的信息。非常感谢您的宝贵时间!
最佳答案
我认为这将是解决方案...
GMailSender sender = new GMailSender(sendEmail, sendPass);
SystemClock.sleep(30000);
sender.sendMail(subject, body, sendEmail, destEmail, path);
这使您的第一封邮件比当前系统时间延迟 30 秒发送,第二封邮件也以这种方式发送...
关于Android:IntentService 未正确排队,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8734441/
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参
我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我在OSX上(如果重要的话)。如果我使用RVM安装Ruby,它会默认将Bundler安装到@globalgemset假设我想要一个不同版本的bundler。我假设我需要做的就是执行geminstallbundler--version但是,这会将bundler安装到默认gemset并且RVM不会为其设置路径。因此,如果我键入bundler,它仍会启动一个与Ruby一起安装到@global中的bundler两个问题:如何将bundler安装到@globalgemset。将bundler安装到@globalgemset中的模式是否正确,或者我遗漏了什么 最佳答案
什么Ruby或RailsDSL会将字符串"mccdougal"格式化为"McDougal",同时留下字符串"McDougal"原样?将titleize传递给"McDougal"结果如下:"McDougal".titleize#=>"McDougal" 最佳答案 据我所知,没有可以处理这种情况的Rails助手。这是一个非标准的边缘案例,需要特殊处理。但是,您可以创建自定义字符串变形。您可以将这段代码放入初始化程序中:ActiveSupport::Inflector.inflections(:en)do|inflect|inflect.
我的一个模型中有一个名为sui的字段。它代表“标准用户标识符”。当该字段出现验证错误时,Rails会打印“Suiisrequired”或“Suiisalreadytaken”。如何告诉Rails'sui'.titleize是“SUI”?我查看了Inflector.human,但这并不完全正确。 最佳答案 在这种情况下,我使用custom_err_msg插入。安装后,您可以提供如下自定义错误消息:validates_presence_of:sui,:message=>'^SUIisrequired'当您将^放在开头时,Rails不会输
我有很多模型和关系。由于这个事实,在View/Controller中有很多调用,看起来像这样:@object.something.with_something.value链的某些部分最终可能为零,这完全没问题。检查终端对象是否存在的正确/干净/快速的方法是什么?正在调用类似的东西:@object.something.with_something.valueifdefined?@object.something.with_something.value还可以吗? 最佳答案 在本地,您需要使用&&运算符(不是defined?),但这很快