You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发中如何将生成的QR码作为图片通过同一封邮件发送

解决方法

你现有代码的核心问题有两个:

  1. 执行顺序颠倒:当前逻辑是先发邮件,再生成二维码,邮件发送时二维码还没生成,自然无法附加
  2. 邮件仅构造了纯文本内容,没有添加附件的逻辑,且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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 11:54:03