Android 自动发送邮件


本文简述的是在Android平台如何自动发送邮件(没有邮件编写界面),主要应用场景为忘记密码等安全等级较高的操作,比如我忘记密码了,点击“发送密码到我的邮箱”系统会将密码发送到注册时的电子邮件地址。

 

Android平台邮件客户端

Gmail: Gmai电子邮件客户端

Email: 通用的电子邮件客户端

 

解决方案

Gmail

Gmail已经支持自动发送了,所以非常简单。在使用时,需要添加

<uses-permission android:name="com.google.android.gm.permission.AUTO_SEND" /> 到AndroidManifest.xml

示例代码如下:

Java代码 复制代码  收藏代码
  1. Intent intent = new Intent("com.google.android.gm.action.AUTO_SEND");   
  2. intent.setType("plain/text");   
  3. String[] reciver = new String[] { "xxxx@xxx.com" };   
  4. String subject = "email title";   
  5. String body = "email body";   
  6. intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver);   
  7. intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);   
  8. intent.putExtra(android.content.Intent.EXTRA_TEXT, body);  
		 Intent intent = new Intent("com.google.android.gm.action.AUTO_SEND");
		 intent.setType("plain/text");
		 String[] reciver = new String[] { "xxxx@xxx.com" };
		 String subject = "email title";
		 String body = "email body";
		 intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver);
		 intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
		 intent.putExtra(android.content.Intent.EXTRA_TEXT, body);

 Email

Email不支持自动发送,但又是默认邮件客户端,所以需要添加自动发送功能。主要实现步骤为:

编写一个自动发送邮件类

主要功能为:接收用户输入,组装message对象,获取Sender实例,将message发送出去,最后删除message对象(这样已发送的邮件内容不会出现在client中,提高发安全性)

Java代码 复制代码  收藏代码
  1. package com.android.email.activity;   
  2.   
  3. import android.app.Activity;   
  4. import android.app.ProgressDialog;   
  5. import android.content.ContentUris;   
  6. import android.content.Context;   
  7. import android.content.Intent;   
  8. import android.os.AsyncTask;   
  9. import android.os.Bundle;   
  10. import android.text.TextUtils;   
  11. import android.util.Log;   
  12. import android.view.View;   
  13. import android.view.Window;   
  14. import android.net.Uri;   
  15. import android.widget.Toast;   
  16.   
  17. import com.android.emailcommon.provider.EmailContent;   
  18. import com.android.emailcommon.provider.EmailContent.Account;   
  19. import com.android.emailcommon.provider.EmailContent.Message;   
  20. import com.android.emailcommon.mail.MessagingException;   
  21. import com.android.emailcommon.mail.Address;   
  22. import com.android.emailcommon.utility.Utility;   
  23. import com.android.emailcommon.mail.AuthenticationFailedException;   
  24. import com.android.email.EmailAddressValidator;   
  25. import com.android.email.mail.Sender;   
  26.   
  27. /**  
  28.  * Send email in background with account configured in Email application. 
  29.  * Sending message will not saved as draft or in out-going box. Usage: 
  30.  *   
  31.  * <pre>  
  32.  * Intent intent = new Intent(&quot;com.android.email.intent.action.sendInBack&quot;); 
  33.  * String[] reciver = new String[] { &quot;your_name@corp.com&quot; }; 
  34.  * String subject = &quot;email title&quot;;  
  35.  * String body = &quot;email body &quot;;  
  36.  * intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver[0]); 
  37.  * intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject); 
  38.  * intent.putExtra(android.content.Intent.EXTRA_TEXT, body); 
  39.  * startActivityForResult(Intent.createChooser(intent, &quot;send&quot;), 0x02); 
  40.  * </pre>  
  41.  *   
  42.  * Now, attachment and multi-receiver function is unsupported. 
  43.  *   
  44.  * @author melord  
  45.  *   
  46.  */  
  47. public class EmailSendAutoActivity extends Activity implements SendListener {   
  48.   
  49.     private static String tag = "EmailSendAutoAcitivity";   
  50.     private Context mContext;   
  51.   
  52.     private String mTo;   
  53.     private String mCc;   
  54.     private String mBcc;   
  55.     private String mSubject;   
  56.     private String mBody;   
  57.   
  58.     private EmailAddressValidator mValidator = new EmailAddressValidator();   
  59.     private SendListener mListener;   
  60.     private Toast mWaiting;   
  61.     private boolean enableLog = true;   
  62.   
  63.     /**  
  64.      * Sending account email address.  
  65.      */  
  66.     private String mSendEmail;   
  67.     /**  
  68.      * Sending account id  
  69.      */  
  70.     private long mAccountId = -1;   
  71.   
  72.     @Override  
  73.     protected void onCreate(Bundle savedInstanceState) {   
  74.         super.onCreate(savedInstanceState);   
  75.         this.mContext = this;   
  76.         requestWindowFeature(Window.FEATURE_NO_TITLE);   
  77.   
  78.         mListener = this;   
  79.         Intent intent = getIntent();   
  80.         initMessageFromIntent(intent);   
  81.         initAccountFromIntent(intent);   
  82.   
  83.         new SendTask().execute();   
  84.         String msg = intent.getStringExtra("sendMsg");   
  85.         if (msg == null) {   
  86.             msg = "Sending message...";   
  87.         }   
  88.         // mWaiting = ProgressDialog.show(this, "", "sending...", true, true,  
  89.         // null);   
  90.         mWaiting = Toast.makeText(this, msg, Toast.LENGTH_LONG);   
  91.         mWaiting.show();   
  92.     }   
  93.   
  94.     @Override  
  95.     public void onBackPressed() {   
  96.         if (mWaiting != null) {   
  97.             mWaiting.cancel();   
  98.         }   
  99.         super.onBackPressed();   
  100.     }   
  101.   
  102.     @Override  
  103.     public void finish() {   
  104.         if (mWaiting != null) {   
  105.             mWaiting.cancel();   
  106.         }   
  107.         super.finish();   
  108.     }   
  109.   
  110.     /**  
  111.      * Initialize sending account from intent.  
  112.      *   
  113.      * @param intent  
  114.      *            imcoming intent  
  115.      */  
  116.     private void initAccountFromIntent(Intent intent) {   
  117.         String email = intent.getStringExtra("sendAccount");   
  118.         if (email != null) {   
  119.             log(String.format("send email use account (%s) ", email));   
  120.             mSendEmail = email;   
  121.             Long[] ids = EmailContent.Account.getAllAccountIds(this);   
  122.             if (ids != null && ids.length > 0) {   
  123.                 for (int i = 0; i < ids.length; i++) {   
  124.                     EmailContent.Account temp = EmailContent.Account   
  125.                             .restoreAccountWithId(this, ids[i]);   
  126.                     if (temp != null && email.equals(temp.getEmailAddress())) {   
  127.                         log("valid account");   
  128.                         mAccountId = ids[i];   
  129.                         break;   
  130.                     }   
  131.                 }   
  132.             }   
  133.         }   
  134.     }   
  135.   
  136.     /**  
  137.      * Initialize message from intent.  
  138.      *   
  139.      * @param intent  
  140.      *            intent  
  141.      */  
  142.     private void initMessageFromIntent(Intent intent) {   
  143.         String to = intent.getStringExtra(Intent.EXTRA_EMAIL);   
  144.         mTo = composeAddress(to);   
  145.   
  146.         String cc = intent.getStringExtra(Intent.EXTRA_CC);   
  147.         mCc = composeAddress(cc);   
  148.   
  149.         String bcc = intent.getStringExtra(Intent.EXTRA_BCC);   
  150.         mBcc = composeAddress(bcc);   
  151.   
  152.         mSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT);   
  153.   
  154.         mBody = intent.getStringExtra(Intent.EXTRA_TEXT);   
  155.   
  156.         log("to:" + mTo);   
  157.         log("cc:" + mCc);   
  158.         log("bcc:" + mBcc);   
  159.   
  160.     }   
  161.   
  162.     /**  
  163.      * change to stand email address reference to Rfc822 
  164.      *   
  165.      * @param address  
  166.      *            email address  
  167.      * @return RFC822 format email address  
  168.      */  
  169.     private String composeAddress(String address) {   
  170.         String addr = null;   
  171.         if (!TextUtils.isEmpty(address)) {   
  172.             Address[] addresses = Address.parse(address.trim());   
  173.             addr = Address.pack(addresses);   
  174.         }   
  175.         return addr;   
  176.     }   
  177.   
  178.     /**  
  179.      * Update message. fill fields.  
  180.      *   
  181.      * @param message  
  182.      *            email message  
  183.      * @param account  
  184.      *            sending account  
  185.      */  
  186.     private void updateMessage(Message message, Account account) {   
  187.         if (message.mMessageId == null || message.mMessageId.length() == 0) {   
  188.             message.mMessageId = Utility.generateMessageId();   
  189.         }   
  190.         message.mTimeStamp = System.currentTimeMillis();   
  191.         // it will : Name<Address>   
  192.         message.mFrom = new Address(account.getEmailAddress(), account   
  193.                 .getSenderName()).pack();   
  194.         message.mTo = mTo;   
  195.         message.mCc = mCc;   
  196.         message.mBcc = mBcc;   
  197.         message.mSubject = mSubject;   
  198.         message.mText = mBody;   
  199.         message.mAccountKey = account.mId;   
  200.         // here just used account setting simply  
  201.         message.mDisplayName = account.getSenderName();   
  202.         message.mFlagRead = true;   
  203.         message.mFlagLoaded = Message.FLAG_LOADED_COMPLETE;   
  204.   
  205.     }   
  206.   
  207.     private void log(String msg) {   
  208.         if (enableLog) {   
  209.             Log.i(tag, msg);   
  210.         }   
  211.     }   
  212.   
  213.     /**  
  214.      * Really send message.  
  215.      *   
  216.      * @param account  
  217.      *            sending account  
  218.      * @param messageId  
  219.      *            message id  
  220.      */  
  221.     public void sendMessage(Account account, long messageId) {   
  222.         // message uri   
  223.         Uri uri = ContentUris.withAppendedId(EmailContent.Message.CONTENT_URI,   
  224.                 messageId);   
  225.         try {   
  226.             // get a sender, ex. smtp sender.  
  227.             Sender sender = Sender.getInstance(mContext, account   
  228.                     .getSenderUri(mContext));   
  229.             // sending started   
  230.             mListener.onStarted(account.mId, messageId);   
  231.             // sending   
  232.             sender.sendMessage(messageId);   
  233.             // send completed   
  234.             mListener.onCompleted(account.mId);   
  235.   
  236.         } catch (MessagingException me) {   
  237.             // report error   
  238.             mListener.onFailed(account.mId, messageId, me);   
  239.         } finally {   
  240.             try {   
  241.                 // delete this message whenever send successfully or not  
  242.                 mContext.getContentResolver().delete(uri, nullnull);   
  243.             } catch (Exception ex) {   
  244.                 Log.w(tag, "delete message occur exception message uri:" + uri);   
  245.             }   
  246.         }   
  247.     }   
  248.   
  249.     public void onCompleted(long accountId) {   
  250.         log("send mail ok");   
  251.         // return Activity.RESULT_OK when send successfully  
  252.         setResult(RESULT_OK);   
  253.         finish();   
  254.     }   
  255.   
  256.     public void onFailed(long accountId, long messageId, Exception ex) {   
  257.         log("send mail failed : " + ex.toString());   
  258.         finish();   
  259.     }   
  260.   
  261.     public void onStarted(long messageId, long accountId) {   
  262.         log("send mail started");   
  263.     }   
  264.   
  265.     /**  
  266.      * Send message task, it is an async task  
  267.      *   
  268.      * @author melord_li  
  269.      *   
  270.      */  
  271.     private class SendTask extends AsyncTask<Void, Void, Void> {   
  272.         @Override  
  273.         protected Void doInBackground(Void... params) {   
  274.             // get default account, if not set, first record is treated as  
  275.             // default.   
  276.             // long id = Account.getDefaultAccountId(mContext);  
  277.             long id = mAccountId;   
  278.             if (id < 0) {   
  279.                 id = Account.getDefaultAccountId(mContext);   
  280.             }   
  281.             if (id < 0) {   
  282.                 Log.w(tag, "no account exists");   
  283.                 finish();   
  284.                 return null;   
  285.             }   
  286.             // get full account message   
  287.             Account account = Account.restoreAccountWithId(mContext, id);   
  288.   
  289.             // A empty message   
  290.             Message message = new Message();   
  291.             // fill message field   
  292.             updateMessage(message, account);   
  293.   
  294.             // Save this message. Because send API will read message in message  
  295.             // db.   
  296.             Uri uri = message.save(mContext);   
  297.             if (uri == null) {   
  298.                 Log.e(tag, "save message occured an error");   
  299.                 finish();   
  300.                 return null;   
  301.             }   
  302.   
  303.             // send   
  304.             sendMessage(account, message.mId);   
  305.             return null;   
  306.         }   
  307.     }   
  308. }   
  309.   
  310. /**  
  311.  * Sending monitor  
  312.  *   
  313.  * @author melord  
  314.  *   
  315.  */  
  316. interface SendListener {   
  317.   
  318.     /**  
  319.      * Send failed.  
  320.      *   
  321.      * @param accountId  
  322.      *            account id  
  323.      * @param messageId  
  324.      *            message id  
  325.      * @param ex  
  326.      *            exception  
  327.      */  
  328.     void onFailed(long accountId, long messageId, Exception ex);   
  329.   
  330.     /**  
  331.      * Send begin.  
  332.      *   
  333.      * @param accountId  
  334.      *            account id  
  335.      * @param messageId  
  336.      *            message id  
  337.      */  
  338.     void onStarted(long messageId, long accountId);   
  339.   
  340.     /**  
  341.      * Send completed.  
  342.      *   
  343.      * @param accountId  
  344.      *            account id  
  345.      */  
  346.     void onCompleted(long accountId);   
  347. }  
package com.android.email.activity;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.net.Uri;
import android.widget.Toast;

import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.mail.Address;
import com.android.emailcommon.utility.Utility;
import com.android.emailcommon.mail.AuthenticationFailedException;
import com.android.email.EmailAddressValidator;
import com.android.email.mail.Sender;

/**
 * Send email in background with account configured in Email application.
 * Sending message will not saved as draft or in out-going box. Usage:
 * 
 * <pre>
 * Intent intent = new Intent(&quot;com.android.email.intent.action.sendInBack&quot;);
 * String[] reciver = new String[] { &quot;your_name@corp.com&quot; };
 * String subject = &quot;email title&quot;;
 * String body = &quot;email body &quot;;
 * intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver[0]);
 * intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
 * intent.putExtra(android.content.Intent.EXTRA_TEXT, body);
 * startActivityForResult(Intent.createChooser(intent, &quot;send&quot;), 0x02);
 * </pre>
 * 
 * Now, attachment and multi-receiver function is unsupported.
 * 
 * @author melord
 * 
 */
public class EmailSendAutoActivity extends Activity implements SendListener {

    private static String tag = "EmailSendAutoAcitivity";
    private Context mContext;

    private String mTo;
    private String mCc;
    private String mBcc;
    private String mSubject;
    private String mBody;

    private EmailAddressValidator mValidator = new EmailAddressValidator();
    private SendListener mListener;
    private Toast mWaiting;
    private boolean enableLog = true;

    /**
     * Sending account email address.
     */
    private String mSendEmail;
    /**
     * Sending account id
     */
    private long mAccountId = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.mContext = this;
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        mListener = this;
        Intent intent = getIntent();
        initMessageFromIntent(intent);
        initAccountFromIntent(intent);

        new SendTask().execute();
        String msg = intent.getStringExtra("sendMsg");
        if (msg == null) {
            msg = "Sending message...";
        }
        // mWaiting = ProgressDialog.show(this, "", "sending...", true, true,
        // null);
        mWaiting = Toast.makeText(this, msg, Toast.LENGTH_LONG);
        mWaiting.show();
    }

    @Override
    public void onBackPressed() {
        if (mWaiting != null) {
            mWaiting.cancel();
        }
        super.onBackPressed();
    }

    @Override
    public void finish() {
        if (mWaiting != null) {
            mWaiting.cancel();
        }
        super.finish();
    }

    /**
     * Initialize sending account from intent.
     * 
     * @param intent
     *            imcoming intent
     */
    private void initAccountFromIntent(Intent intent) {
        String email = intent.getStringExtra("sendAccount");
        if (email != null) {
            log(String.format("send email use account (%s) ", email));
            mSendEmail = email;
            Long[] ids = EmailContent.Account.getAllAccountIds(this);
            if (ids != null && ids.length > 0) {
                for (int i = 0; i < ids.length; i++) {
                    EmailContent.Account temp = EmailContent.Account
                            .restoreAccountWithId(this, ids[i]);
                    if (temp != null && email.equals(temp.getEmailAddress())) {
                        log("valid account");
                        mAccountId = ids[i];
                        break;
                    }
                }
            }
        }
    }

    /**
     * Initialize message from intent.
     * 
     * @param intent
     *            intent
     */
    private void initMessageFromIntent(Intent intent) {
        String to = intent.getStringExtra(Intent.EXTRA_EMAIL);
        mTo = composeAddress(to);

        String cc = intent.getStringExtra(Intent.EXTRA_CC);
        mCc = composeAddress(cc);

        String bcc = intent.getStringExtra(Intent.EXTRA_BCC);
        mBcc = composeAddress(bcc);

        mSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT);

        mBody = intent.getStringExtra(Intent.EXTRA_TEXT);

        log("to:" + mTo);
        log("cc:" + mCc);
        log("bcc:" + mBcc);

    }

    /**
     * change to stand email address reference to Rfc822
     * 
     * @param address
     *            email address
     * @return RFC822 format email address
     */
    private String composeAddress(String address) {
        String addr = null;
        if (!TextUtils.isEmpty(address)) {
            Address[] addresses = Address.parse(address.trim());
            addr = Address.pack(addresses);
        }
        return addr;
    }

    /**
     * Update message. fill fields.
     * 
     * @param message
     *            email message
     * @param account
     *            sending account
     */
    private void updateMessage(Message message, Account account) {
        if (message.mMessageId == null || message.mMessageId.length() == 0) {
            message.mMessageId = Utility.generateMessageId();
        }
        message.mTimeStamp = System.currentTimeMillis();
        // it will : Name<Address>
        message.mFrom = new Address(account.getEmailAddress(), account
                .getSenderName()).pack();
        message.mTo = mTo;
        message.mCc = mCc;
        message.mBcc = mBcc;
        message.mSubject = mSubject;
        message.mText = mBody;
        message.mAccountKey = account.mId;
        // here just used account setting simply
        message.mDisplayName = account.getSenderName();
        message.mFlagRead = true;
        message.mFlagLoaded = Message.FLAG_LOADED_COMPLETE;

    }

    private void log(String msg) {
        if (enableLog) {
            Log.i(tag, msg);
        }
    }

    /**
     * Really send message.
     * 
     * @param account
     *            sending account
     * @param messageId
     *            message id
     */
    public void sendMessage(Account account, long messageId) {
        // message uri
        Uri uri = ContentUris.withAppendedId(EmailContent.Message.CONTENT_URI,
                messageId);
        try {
            // get a sender, ex. smtp sender.
            Sender sender = Sender.getInstance(mContext, account
                    .getSenderUri(mContext));
            // sending started
            mListener.onStarted(account.mId, messageId);
            // sending
            sender.sendMessage(messageId);
            // send completed
            mListener.onCompleted(account.mId);

        } catch (MessagingException me) {
            // report error
            mListener.onFailed(account.mId, messageId, me);
        } finally {
            try {
                // delete this message whenever send successfully or not
                mContext.getContentResolver().delete(uri, null, null);
            } catch (Exception ex) {
                Log.w(tag, "delete message occur exception message uri:" + uri);
            }
        }
    }

    public void onCompleted(long accountId) {
        log("send mail ok");
        // return Activity.RESULT_OK when send successfully
        setResult(RESULT_OK);
        finish();
    }

    public void onFailed(long accountId, long messageId, Exception ex) {
        log("send mail failed : " + ex.toString());
        finish();
    }

    public void onStarted(long messageId, long accountId) {
        log("send mail started");
    }

    /**
     * Send message task, it is an async task
     * 
     * @author melord_li
     * 
     */
    private class SendTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            // get default account, if not set, first record is treated as
            // default.
            // long id = Account.getDefaultAccountId(mContext);
            long id = mAccountId;
            if (id < 0) {
                id = Account.getDefaultAccountId(mContext);
            }
            if (id < 0) {
                Log.w(tag, "no account exists");
                finish();
                return null;
            }
            // get full account message
            Account account = Account.restoreAccountWithId(mContext, id);

            // A empty message
            Message message = new Message();
            // fill message field
            updateMessage(message, account);

            // Save this message. Because send API will read message in message
            // db.
            Uri uri = message.save(mContext);
            if (uri == null) {
                Log.e(tag, "save message occured an error");
                finish();
                return null;
            }

            // send
            sendMessage(account, message.mId);
            return null;
        }
    }
}

/**
 * Sending monitor
 * 
 * @author melord
 * 
 */
interface SendListener {

    /**
     * Send failed.
     * 
     * @param accountId
     *            account id
     * @param messageId
     *            message id
     * @param ex
     *            exception
     */
    void onFailed(long accountId, long messageId, Exception ex);

    /**
     * Send begin.
     * 
     * @param accountId
     *            account id
     * @param messageId
     *            message id
     */
    void onStarted(long messageId, long accountId);

    /**
     * Send completed.
     * 
     * @param accountId
     *            account id
     */
    void onCompleted(long accountId);
}
 配置
Xml代码 复制代码  收藏代码
  1. <activity android:name=".activity.EmailSendAutoActivity" android:theme="@android:style/Theme.Translucent">  
  2.     <intent-filter>  
  3.         <action android:name="com.android.email.intent.action.sendInBack"/>  
  4.         <data android:mimeType="*/*" />  
  5.         <category android:name="android.intent.category.DEFAULT" />  
  6.     </intent-filter>  
  7. </activity>  
 使用
Java代码 复制代码  收藏代码
  1. Intent intent = new Intent("com.android.email.intent.action.sendInBack");   
  2. String[] reciver = new String[] { "yourname@corp.com" };   
  3. String subject = "email title";   
  4. String body = "email body";   
  5. intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver[0]);   
  6. intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);   
  7. intent.putExtra(android.content.Intent.EXTRA_TEXT, body);   
  8.   
  9. startActivityForResult(Intent.createChooser(intent, "send"), 0x02);  
		Intent intent = new Intent("com.android.email.intent.action.sendInBack");
		String[] reciver = new String[] { "yourname@corp.com" };
		String subject = "email title";
		String body = "email body";
		intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver[0]);
		intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
		intent.putExtra(android.content.Intent.EXTRA_TEXT, body);

		startActivityForResult(Intent.createChooser(intent, "send"), 0x02);
 处理回调

如果发送成功,会返回RESULT_OK。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值