Android开发中如何将生成的QR码作为图片通过同一封邮件发送
解决方法
你现有代码的核心问题有两个:
- 执行顺序颠倒:当前逻辑是先发邮件,再生成二维码,邮件发送时二维码还没生成,自然无法附加
- 邮件仅构造了纯文本内容,没有添加附件的逻辑,且
messageToSend末尾拼接image(ImageView对象)属于无效操作,只会输出对象内存地址
具体修改步骤
- 第一步:调整执行顺序,先生成二维码Bitmap,再构造邮件发送
- 第二步:将生成的二维码Bitmap转为字节流,作为邮件附件嵌入,不需要额外存储到本地文件
- 第三步:将原纯文本邮件改为支持附件的多部分(Multipart)邮件格式
修正后的核心代码
EditText correo, nombre; Button procesar; ImageView image; String texto="Santa Cruz \nAsientos:4 \nFecha:30/11/21 15:00 \nAsientos: 5,6,7 \nBus: CAMA \nCod_Bus: 0010"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tarjeta); procesar=(Button) findViewById(R.id.procesar); correo=(EditText) findViewById(R.id.correo); nombre=(EditText) findViewById(R.id.nombre); image=(ImageView) findViewById(R.id.iv); procesar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 先生成二维码 Bitmap qrBitmap = null; MultiFormatWriter writer= new MultiFormatWriter(); try { BitMatrix matrix=writer.encode(texto, BarcodeFormat.QR_CODE ,350,350); BarcodeEncoder encoder= new BarcodeEncoder(); qrBitmap = encoder.createBitmap(matrix); image.setImageBitmap(qrBitmap); InputMethodManager manager= (InputMethodManager) getSystemService( Context.INPUT_METHOD_SERVICE ); manager.hideSoftInputFromWindow(correo.getApplicationWindowToken(),0); } catch (WriterException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(),"二维码生成失败",Toast.LENGTH_SHORT).show(); return; } // 再构造发送带附件的邮件 final String username="termin@gmail.com"; final String password="password"; String messageToSend="Este es el ticket para el cliente: "+nombre.getText().toString() +" GRACIAS POR COMPRAR"; Properties props=new Properties(); props.put("mail.smtp.auth","true"); props.put("mail.smtp.starttls.enable","true"); props.put("mail.smtp.host","smtp.gmail.com"); props.put("mail.smtp.port","587"); Session session= Session.getInstance(props, new Authenticator(){ @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username,password); } }); try { Message message= new MimeMessage(session); message.setFrom(new InternetAddress(username)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(correo.getText().toString())); message.setSubject("Enviando mensaje"); // 构造多部分邮件内容 Multipart multipart = new MimeMultipart(); // 添加文本部分 BodyPart textPart = new MimeBodyPart(); textPart.setText(messageToSend); multipart.addBodyPart(textPart); // 添加二维码附件部分 if(qrBitmap != null){ BodyPart imagePart = new MimeBodyPart(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); qrBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] imageBytes = baos.toByteArray(); DataSource source = new ByteArrayDataSource(imageBytes, "image/png"); imagePart.setDataHandler(new DataHandler(source)); imagePart.setFileName("ticket_qr.png"); multipart.addBodyPart(imagePart); } // 设置邮件内容 message.setContent(multipart); Transport.send(message); Toast.makeText(getApplicationContext(),"Ticket Enviado correctamente a :"+correo.getText().toString(),Toast.LENGTH_LONG).show(); }catch (MessagingException | IOException e){ throw new RuntimeException(e); } } }); StrictMode.ThreadPolicy policy= new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); }
注意事项
- 你当前使用的Gmail普通账号密码登录SMTP的方式已被谷歌官方限制,需要先给账号开启两步验证,再生成应用专用密码替换代码里的
password字段才能正常发信 - 生产环境不要直接在主线程执行网络请求和二维码生成操作,建议换成协程或者AsyncTask处理,避免触发ANR问题
内容的提问来源于stack exchange,提问作者Jhon Torrez
相关产品推荐
相关产品推荐

