700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android 基于bmob平台的手机登录验证码注册 等功能实现

Android 基于bmob平台的手机登录验证码注册 等功能实现

时间:2019-04-15 10:46:16

相关推荐

Android 基于bmob平台的手机登录验证码注册 等功能实现

首先是基于Bmob 平台,采用MVP 开发模式。效果见图:

下面一 一给出源码:

MVP 目录结构:

登录/注册的Activity:

package com.example.yangzi.mvp_dev.ui.activity;import android.content.Context;import android.content.Intent;import android.support.design.widget.TextInputLayout;import android.text.Editable;import android.text.TextWatcher;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import com.example.yangzi.mvp_dev.R;import com.example.yangzi.mvp_dev.base.BaseActivity;import com.example.yangzi.mvp_dev.bean.remote.MyUser;import com.example.yangzi.mvp_dev.mvp.presenter.Imp.UserLogPresenterImp;import com.example.yangzi.mvp_dev.mvp.presenter.UserLogPresenter;import com.example.yangzi.mvp_dev.mvp.view.UserLogView;import com.example.yangzi.mvp_dev.utils.LogUtils;import com.example.yangzi.mvp_dev.utils.ProgressUtils;import com.example.yangzi.mvp_dev.utils.RegexUtils;import com.example.yangzi.mvp_dev.utils.SnackbarUtils;import com.example.yangzi.mvp_dev.utils.StringUtils;import com.example.yangzi.mvp_dev.utils.ToastUtils;import com.example.yangzi.mvp_dev.widget.OwlView;import com.example.yangzi.mvp_dev.widget.VerifyCodeButton;import java.util.HashMap;import java.util.List;import butterknife.BindView;import butterknife.OnClick;import butterknife.OnFocusChange;import cn.bmob.v3.BmobQuery;import cn.bmob.v3.BmobSMS;import cn.bmob.v3.BmobUser;import cn.bmob.v3.exception.BmobException;import cn.bmob.v3.listener.FindListener;import cn.bmob.v3.listener.QueryListener;import cn.bmob.v3.listener.UpdateListener;import cn.smssdk.EventHandler;import cn.smssdk.SMSSDK;import cn.smssdk.gui.RegisterPage;/*** Created by linzihahaha on /12/8.*/public class LoginActivity extends BaseActivity implements UserLogView {@BindView(R.id.owl_view)OwlView mOwlView;@BindView(R.id.login_et_username)TextInputLayout usernameET;@BindView(R.id.login_et_password)EditText passwordET;@BindView(R.id.login_tv_forget)TextView forget;@BindView(R.id.login_et_rpassword)EditText rpasswordET;@BindView(R.id.login_et_phone)TextInputLayout phone;@BindView(R.id.login_et_email)TextInputLayout email;@BindView(R.id.login_get_code)TextInputLayout getCode;@BindView(R.id.login_tv_sign)TextView signTV;@BindView(R.id.login_tv_phone)TextView loginphoneTV;@BindView(R.id.btn_login_get_code)VerifyCodeButton getcodeBtn;@BindView(R.id.login_btn_login)Button loginBtn;private EditText mEdtName;private EditText mEdtPhone;private EditText mEdtEmail;private EditText mEdtCode;private EditText mEdtPassword;private EditText mEdtrPassword;//是否是登陆操作private boolean isLogin = true;private boolean isLoginbyphone = false;private UserLogPresenter userLogPresenter;@Overrideprotected int getLayout() {return R.layout.activity_user_login;}@Overrideprotected void initEventAndData() {userLogPresenter = new UserLogPresenterImp(this);mEdtName = usernameET.getEditText();mEdtPhone = phone.getEditText();mEdtEmail=email.getEditText();mEdtCode = getCode.getEditText();mEdtName.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {usernameET.setErrorEnabled(false);}@Overridepublic void afterTextChanged(Editable editable) {}});mEdtPhone.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {String phone = charSequence.toString();if (!RegexUtils.checkPhone(phone)) {mEdtPhone.setError("请输入正确的手机号");} else {getCode.setErrorEnabled(false);}}@Overridepublic void afterTextChanged(Editable editable) {}});mEdtEmail.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {String phone = charSequence.toString();if (!RegexUtils.checkPhone(phone)) {mEdtPhone.setError("请输入正确的邮箱");} else {getCode.setErrorEnabled(false);}}@Overridepublic void afterTextChanged(Editable editable) {}});mEdtCode.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {String code = charSequence.toString();if (!RegexUtils.checkCode(code)) {getCode.setError("请输入正确的验证码");} else {getCode.setErrorEnabled(false);}}@Overridepublic void afterTextChanged(Editable editable) {}});}//监听密码输入框的聚焦事件@OnFocusChange({R.id.login_et_password,R.id.login_et_rpassword})public void onFocusChange(View view, boolean b) {if (b) {mOwlView.open();} else {mOwlView.close();}}/*** 监听点击事件** @param view*/@OnClick({R.id.btn_login_get_code,R.id.login_tv_sign, R.id.login_btn_login, R.id.login_tv_forget,R.id.login_tv_phone})protected void onClick(View view) {switch (view.getId()) {case R.id.btn_login_get_code: // 获取验证码getCode();break;case R.id.login_btn_login: //buttonif (isLogin) {login(); //登陆} else {sign(); //注册}break;case R.id.login_tv_forget: //忘记密码startActivity(new Intent(mContext, ForgetPasswordActivity.class));break;case R.id.login_tv_sign: //signif (!isLogin) {//置换注册界面if (!isLoginbyphone) {loginBtn.setText("登录");signTV.setText("邮箱注册");loginphoneTV.setText("验证码注册");usernameET.setVisibility(View.VISIBLE);passwordET.setVisibility(View.VISIBLE);rpasswordET.setVisibility(View.GONE);phone.setVisibility(View.GONE);email.setVisibility(View.GONE);getCode.setVisibility(View.GONE);forget.setVisibility(View.VISIBLE);getcodeBtn.setVisibility(View.GONE);usernameET.setHint("用户名/手机号/邮箱");}else{loginBtn.setText("验证");signTV.setText("邮箱注册");loginphoneTV.setText("密码登录");usernameET.setVisibility(View.GONE);passwordET.setVisibility(View.GONE);rpasswordET.setVisibility(View.GONE);phone.setVisibility(View.VISIBLE);email.setVisibility(View.GONE);getCode.setVisibility(View.VISIBLE);forget.setVisibility(View.GONE);getcodeBtn.setVisibility(View.VISIBLE);usernameET.setHint("用户名");}} else {//置换登陆界面loginBtn.setText("注册");signTV.setText("返回登录");usernameET.setVisibility(View.VISIBLE);passwordET.setVisibility(View.VISIBLE);rpasswordET.setVisibility(View.VISIBLE);phone.setVisibility(View.GONE);email.setVisibility(View.VISIBLE);getCode.setVisibility(View.GONE);forget.setVisibility(View.GONE);getcodeBtn.setVisibility(View.GONE);usernameET.setHint("用户名");}isLogin = !isLogin;break;case R.id.login_tv_phone: //手机号验证码登录isLogin=true;if (isLoginbyphone) {loginBtn.setText("登录");signTV.setText("邮箱注册");loginphoneTV.setText("验证码注册");usernameET.setVisibility(View.VISIBLE);passwordET.setVisibility(View.VISIBLE);rpasswordET.setVisibility(View.GONE);phone.setVisibility(View.GONE);email.setVisibility(View.GONE);getCode.setVisibility(View.GONE);forget.setVisibility(View.VISIBLE);getcodeBtn.setVisibility(View.GONE);usernameET.setHint("用户名/手机号/邮箱");}else{loginBtn.setText("验证");signTV.setText("邮箱注册");loginphoneTV.setText("密码登录");usernameET.setVisibility(View.GONE);passwordET.setVisibility(View.GONE);rpasswordET.setVisibility(View.GONE);phone.setVisibility(View.VISIBLE);email.setVisibility(View.GONE);getCode.setVisibility(View.VISIBLE);forget.setVisibility(View.GONE);getcodeBtn.setVisibility(View.VISIBLE);usernameET.setHint("用户名");}isLoginbyphone=!isLoginbyphone;break;default:break;}}private void getCode() {String username = mEdtName.getText().toString();String password = passwordET.getText().toString();String rpassword = rpasswordET.getText().toString();final String phonenumber = mEdtPhone.getText().toString();if (phonenumber.length() == 0) {Toast.makeText(mContext, "请输入手机号", Toast.LENGTH_SHORT).show();return;}BmobQuery<MyUser> query = new BmobQuery<MyUser>();query.addWhereEqualTo("mobilePhoneNumber", phonenumber);query.setLimit(1);query.findObjects(new FindListener<MyUser>() {@Overridepublic void done(List<MyUser> list, BmobException e) {if (e == null) {if (list.size()>0)Toast.makeText(mContext, "手机号已注册,请返回登录", Toast.LENGTH_SHORT).show();elserequestSMScodeFromBmob(phonenumber);}}});// 请求验证码,其中country表示国家代码,如“86”;phone表示手机号码,如“13800138000”//Toast.makeText(mContext, "发送验证码请求" + username, Toast.LENGTH_SHORT).show();//SMSSDK.getVerificationCode("86",username);}/*** 请求验证码* @param phone_number 手机号* @param template_name 验证码模板名称* @param listener 回调*//*** TODO template 如果是自定义短信模板,此处替换为你在控制台设置的自定义短信模板名称;如果没有对应的自定义短信模板,则使用默认短信模板。*/public void requestSMScodeFromBmob(String phone) {getcodeBtn.start();BmobSMS.requestSMSCode(phone, "register", new QueryListener<Integer>() {@Overridepublic void done(Integer smsId, BmobException e) {if (e == null) {Toast.makeText(mContext, "发送验证码成功,短信ID:" + smsId + "\n", Toast.LENGTH_SHORT).show();} else {Toast.makeText(mContext, "发送验证码失败:" + e.getErrorCode() + "-" + e.getMessage() + "\n", Toast.LENGTH_SHORT).show();}}});}/*** 执行登陆动作*/public void login() {if(!isLoginbyphone) {String username = mEdtName.getText().toString();String password = passwordET.getText().toString();if (username.length() == 0 || password.length() == 0 ) {SnackbarUtils.show(mContext, "输入为空或格式不正确");return;}ProgressUtils.show(this, "正在登陆...");userLogPresenter.login(username, password);}else{String phonenumber = mEdtPhone.getText().toString();String code = mEdtCode.getText().toString();if (phonenumber.length() == 0 || !RegexUtils.checkPhone(phonenumber)) {Toast.makeText(mContext, "请输入正确手机号", Toast.LENGTH_SHORT).show();return;}if (code.length() == 0|| !RegexUtils.checkCode(code)) {Toast.makeText(mContext, "请输入正确验证码", Toast.LENGTH_SHORT).show();return;}ProgressUtils.show(this, "正在验证...");veriflySMSCode(phonenumber,code);}}/*** 执行注册动作*/public void sign() {String username = mEdtName.getText().toString();String password = passwordET.getText().toString();String rpassword = rpasswordET.getText().toString();String email= mEdtEmail.getText().toString();String phone = mEdtPhone.getText().toString();if ( username.length() == 0 || password.length() == 0 || rpassword.length() == 0) {SnackbarUtils.show(mContext, "请填写必要信息");return;}if (!RegexUtils.checkUserName(username)) {SnackbarUtils.show(mContext, "请输入正确用户名 6到18位字母开头与字数组合");return;}//ToastUtils.show(mContext,"xxxx"+password+"||"+rpassword);if (!password.equals(rpassword)|| !RegexUtils.checkPassword(password)) {SnackbarUtils.show(mContext, "两次密码不一致");return;}ProgressUtils.show(this, "正在注册...");if (!isLogin && !isLoginbyphone) {emailVerify(email);userLogPresenter.signup(username,password,email);}elseuserLogPresenter.signup(username,password,phone);}/*** 发送验证邮件*/private void emailVerify(final String email) {MyUser.requestEmailVerify(email, new UpdateListener() {@Overridepublic void done(BmobException e) {if (e == null) {ToastUtils.show(mContext, "请求验证邮件成功,请到" + email + "邮箱中进行激活账户。");} else {Log.e("BMOB", e.toString());ToastUtils.show(mContext, "请求验证邮件失败," + e.getMessage());}}});}private void veriflySMSCode(final String phonenumber,final String code) {BmobSMS.verifySmsCode(phonenumber, code, new UpdateListener() {@Overridepublic void done(BmobException e) {if (e == null) {ToastUtils.show(mContext, "验证码验证成功");ProgressUtils.dismiss();if(phone.isShown()){//ToastUtils.show(mContext, "该手机号第一次登录,请设置用户名密码");isLogin=false;loginBtn.setText("注册");loginphoneTV.setText("密码登录");usernameET.setVisibility(View.VISIBLE);passwordET.setVisibility(View.VISIBLE);rpasswordET.setVisibility(View.VISIBLE);phone.setVisibility(View.GONE);getCode.setVisibility(View.GONE);forget.setVisibility(View.VISIBLE);getcodeBtn.setVisibility(View.GONE);usernameET.setHint("用户名");}} else {ProgressUtils.dismiss();ToastUtils.show(mContext, "验证码有误"+e.getErrorCode() + "-" + e.getMessage());}}});}@Overridepublic void loadDataSuccess(MyUser tData) {ProgressUtils.dismiss();if (isLogin) {ToastUtils.show(mContext, "登录成功");setResult(RESULT_OK, new Intent());finish();}else {ToastUtils.show(mContext, "注册成功");if (tData.getEmail()==null){setResult(RESULT_OK, new Intent());finish();}else {//emailVerify(tData.getEmail());SnackbarUtils.show(mContext, "请先登陆邮箱验证后登陆");}}}@Overridepublic void loadDataError(Throwable throwable) {ProgressUtils.dismiss();SnackbarUtils.show(mContext, throwable.getMessage());Log.v(LogUtils.filename(new Exception()),LogUtils.funAndLine(new Exception())+throwable.getMessage());}}

用户信息展示Activity:

package com.example.yangzi.mvp_dev.ui.activity;import android.Manifest;import android.app.Activity;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageManager;import android.graphics.Bitmap;import .Uri;import android.os.Build;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.support.annotation.NonNull;import android.support.v4.content.ContextCompat;import android.support.v4.content.FileProvider;import android.support.v7.app.AlertDialog;import android.support.v7.widget.Toolbar;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.widget.EditText;import android.widget.ImageView;import android.widget.RelativeLayout;import android.widget.Toast;import com.bumptech.glide.Glide;import com.example.yangzi.mvp_dev.R;import com.example.yangzi.mvp_dev.base.BaseActivity;import com.example.yangzi.mvp_dev.bean.remote.MyUser;import com.example.mon.Constants;import com.example.yangzi.mvp_dev.mvp.presenter.Imp.UserInfoPresenterImp;import com.example.yangzi.mvp_dev.mvp.presenter.UserInfoPresenter;import com.example.yangzi.mvp_dev.mvp.view.UserInfoView;import com.example.yangzi.mvp_dev.utils.ImageUtils;import com.example.yangzi.mvp_dev.utils.LogUtils;import com.example.yangzi.mvp_dev.utils.ProgressUtils;import com.example.yangzi.mvp_dev.utils.SnackbarUtils;import com.example.yangzi.mvp_dev.utils.StringUtils;import com.example.yangzi.monItemLayout;import java.io.File;import java.util.List;import butterknife.BindView;import butterknife.OnClick;import cn.bmob.v3.BmobQuery;import cn.bmob.v3.datatype.BmobFile;import cn.bmob.v3.exception.BmobException;import cn.bmob.v3.listener.FindListener;import cn.bmob.v3.listener.UpdateListener;import cn.bmob.v3.listener.UploadFileListener;import cn.smssdk.gui.util.Const;/*** Created by linzihahaha on /12/24.* 用户信息管理中心*/public class UserInfoActivity extends BaseActivity implements UserInfoView {@BindView(R.id.toolbar)Toolbar toolbar;@BindView(R.id.rlt_update_icon)RelativeLayout iconRL;@BindView(R.id.img_icon)ImageView iconIv;@BindView(R.id.cil_username)CommonItemLayout usernameCL;@BindView(R.id.cil_sex)CommonItemLayout sexCL;@BindView(R.id.cil_phone)CommonItemLayout phoneCL;@BindView(R.id.cil_email)CommonItemLayout emailCL;private UserInfoPresenter presenter;//选择图片来源private AlertDialog iconDialog;private AlertDialog genderDialog;private AlertDialog phoneDialog;private AlertDialog emailDialog;protected static final int CHOOSE_PICTURE = 0;protected static final int TAKE_PICTURE = 1;protected static final int GENDER_MAN = 0;protected static final int GENDER_FEMALE = 1;private static final int CROP_SMALL_PICTURE = 2;//图片路径protected static Uri tempUri = null;@Overrideprotected int getLayout() {return R.layout.activity_user_info;}@Overrideprotected void initEventAndData() {presenter = new UserInfoPresenterImp(this);presenter.showUserInfor(toolbar,currentUser);}@Overridepublic void loadDataSuccess(MyUser tData) {ProgressUtils.dismiss();}@Overridepublic void loadDataError(Throwable throwable) {ProgressUtils.dismiss();SnackbarUtils.show(mContext, throwable.getMessage());}@Overridepublic void showUserInfor(Toolbar toolbar, MyUser user) {//初始化Toolbartoolbar.setTitle("账户");setSupportActionBar(toolbar);getSupportActionBar().setDisplayHomeAsUpEnabled(true);toolbar.setNavigationOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//返回消息更新上个Activity数据setResult(RESULT_OK, new Intent());finish();}});if (currentUser != null) {//加载到布局中//加载当前头像Glide.with(mContext).load(currentUser.getImage()).into(iconIv);usernameCL.setRightText(currentUser.getUsername());sexCL.setRightText(currentUser.getGender());phoneCL.setRightText(currentUser.getMobilePhoneNumber());emailCL.setRightText(currentUser.getEmail());}}/*** 监听点击事件** @param view*/@OnClick({R.id.rlt_update_icon, R.id.cil_username,R.id.cil_sex, R.id.cil_phone, R.id.cil_email})public void onViewClicked(final View view) {switch (view.getId()) {case R.id.rlt_update_icon: //头像//showIconDialog();Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);openAlbumIntent.setType("image/*");startActivityForResult(openAlbumIntent, CHOOSE_PICTURE);break;case R.id.cil_username: //用户名SnackbarUtils.show(mContext, "江湖人行不更名,坐不改姓!");break;case R.id.cil_sex: //性别showGenderDialog();break;case R.id.cil_phone: //电话修改showPhoneDialog();break;case R.id.cil_email: //邮箱修改showMailDialog();break;default:break;}}/*** 更新用户数据*/public void doUpdate() {if (currentUser == null)return;Log.v(LogUtils.filename(new Exception()),LogUtils.funAndLine(new Exception())+"doUpdate");ProgressUtils.show(UserInfoActivity.this, "正在修改...");presenter.update(currentUser);}/*** 显示选择性别对话框*/public void showGenderDialog() {if (genderDialog == null) {genderDialog = new AlertDialog.Builder(this).setItems(new String[]{"男", "女"},new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {switch (which) {case GENDER_MAN: // 男性currentUser.setGender("男");doUpdate();break;case GENDER_FEMALE: // 女性currentUser.setGender("女");doUpdate();break;}sexCL.setRightText(currentUser.getGender());}}).create();}if (!genderDialog.isShowing()) {genderDialog.show();}}/*** 显示更换电话对话框*/public void showPhoneDialog() {final EditText editText = new EditText(mContext);String phone = currentUser.getMobilePhoneNumber();if (phone != null) {SnackbarUtils.show(mContext, "已绑定,可进入设置更换!");return;}if (phoneDialog == null) {phoneDialog = new AlertDialog.Builder(this).setTitle("绑定手机号").setMessage("请输入新手机号").setView(editText).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {final String input = editText.getText().toString();if (input.equals("")) {Toast.makeText(getApplicationContext(), "内容不能为空!" + input,Toast.LENGTH_SHORT).show();} else {if (StringUtils.checkPhoneNumber(input)) {BmobQuery<MyUser> query = new BmobQuery<MyUser>();query.addWhereEqualTo("mobilePhoneNumber", input);query.setLimit(1);query.findObjects(new FindListener<MyUser>() {@Overridepublic void done(List<MyUser> list, BmobException e) {if (e == null) {if (list.size()>0)Toast.makeText(mContext, "手机号已注册!", Toast.LENGTH_SHORT).show();else{verifyPhone(Constants.VERI_ADD_PHONE,input);}}}});} else {Toast.makeText(UserInfoActivity.this,"请输入正确的电话号码", Toast.LENGTH_LONG).show();}}}}).setNegativeButton("取消", null).create();}if (!phoneDialog.isShowing()) {phoneDialog.show();}}/**手机号码验证*/private void verifyPhone(int index,String input) {Intent intent = new Intent();Bundle bundle = new Bundle();bundle.putString("phoneNumber",input);bundle.putString("index",""+index);intent.putExtras(bundle);intent.setClass(this, VerifyPhoneActivity.class);startActivityForResult(intent,index);}/*** 显示更换邮箱对话框*/public void showMailDialog() {final EditText emailEditText = new EditText(UserInfoActivity.this);emailEditText.setText(currentUser.getEmail());String title = "添加邮箱";if(currentUser.getEmail()!=null) {title = "更换邮箱";//将光标移至文字末尾emailEditText.setSelection(currentUser.getEmail().length());}if (emailDialog == null) {emailDialog = new AlertDialog.Builder(this).setTitle(title).setView(emailEditText).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {final String input = emailEditText.getText().toString();if (input.equals("")) {Toast.makeText(getApplicationContext(), "内容不能为空!" + input,Toast.LENGTH_SHORT).show();} else {if (StringUtils.checkEmail(input)) {currentUser.setEmail(input);BmobQuery<MyUser> query = new BmobQuery<MyUser>();query.addWhereEqualTo("mobilePhoneNumber", input);query.setLimit(1);query.findObjects(new FindListener<MyUser>() {@Overridepublic void done(List<MyUser> list, BmobException e) {if (e == null) {if (list.size()>0)Toast.makeText(mContext, "邮箱已注册!", Toast.LENGTH_SHORT).show();else{//Toast.makeText(mContext, "请登录邮箱激活!", Toast.LENGTH_SHORT).show();emailCL.setRightText(input);doUpdate();}}}});} else {Toast.makeText(UserInfoActivity.this,"请输入正确的邮箱格式", Toast.LENGTH_LONG).show();}}}}).setNegativeButton("取消", null).create();}if (!emailDialog.isShowing()) {emailDialog.show();}}/*** 监听Activity返回结果** @param requestCode* @param resultCode* @param intent*/@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent intent) {if (resultCode == RESULT_OK) {switch (requestCode) {case TAKE_PICTURE:startPhotoZoom(tempUri); // 开始对图片进行裁剪处理break;case CHOOSE_PICTURE:startPhotoZoom(intent.getData()); // 开始对图片进行裁剪处理break;case CROP_SMALL_PICTURE:if (intent != null) {setImageToView(intent); // 让刚才选择裁剪得到的图片显示在界面上}break;case Constants.VERI_ADD_PHONE :Log.v(LogUtils.filename(new Exception()),LogUtils.funAndLine(new Exception())+intent.getStringExtra("phone"));//Toast.makeText(mContext, "手机绑定成功", Toast.LENGTH_SHORT).show();currentUser.setMobilePhoneNumber(intent.getStringExtra("phone"));phoneCL.setRightText(intent.getStringExtra("phone"));doUpdate();break;}}}/*** 监听Back键按下事件,方法2:* 注意:* 返回值表示:是否能完全处理该事件* 在此处返回false,所以会继续传播该事件.* 在具体项目中此处的返回值视情况而定.*/@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if ((keyCode == KeyEvent.KEYCODE_BACK))setResult(RESULT_OK, new Intent());return super.onKeyDown(keyCode, event);}/*** 拍照*/private void takePicture() {String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};if (Build.VERSION.SDK_INT >= 23) {// 需要申请动态权限int check = ContextCompat.checkSelfPermission(this, permissions[0]);// 权限是否已经 授权 GRANTED---授权 DINIED---拒绝if (check != PackageManager.PERMISSION_GRANTED) {requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);}}Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);File file = new File(Environment.getExternalStorageDirectory(), "image.jpg");//判断是否是AndroidN以及更高的版本if (Build.VERSION.SDK_INT >= 24) {openCameraIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);tempUri = FileProvider.getUriForFile(UserInfoActivity.this,"com.copasso.cocobill.fileProvider", file);} else {tempUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "image.jpg"));}// 指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);startActivityForResult(openCameraIntent, TAKE_PICTURE);}/*** 裁剪图片方法实现** @param uri*/protected void startPhotoZoom(Uri uri) {if (uri == null) {Log.i("tag", "The uri is not exist.");}tempUri = uri;Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(uri, "image/*");// 设置裁剪intent.putExtra("crop", "true");// aspectX aspectY 是宽高的比例intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);// outputX outputY 是裁剪图片宽高intent.putExtra("outputX", 150);intent.putExtra("outputY", 150);intent.putExtra("return-data", true);startActivityForResult(intent, CROP_SMALL_PICTURE);}/*** 保存裁剪之后的图片数据** @param data*/protected void setImageToView(Intent data) {Bundle extras = data.getExtras();if (extras != null) {Bitmap photo = extras.getParcelable("data");photo = ImageUtils.toRoundBitmap(photo); // 这个时候的图片已经被处理成圆形的了iconIv.setImageBitmap(photo);uploadPic(photo);}}/*** 保存头像并上传服务器** @param bitmap*/private void uploadPic(Bitmap bitmap) {// 上传至服务器// 可以在这里把Bitmap转换成file,然后得到file的url,做文件上传操作// 注意这里得到的图片已经是圆形图片了// bitmap是没有做个圆形处理的,但已经被裁剪了String imagename = currentUser.getObjectId() + "_" + String.valueOf(System.currentTimeMillis());String imagePath = ImageUtils.savePhoto(bitmap, Environment.getExternalStorageDirectory().getAbsolutePath(), imagename + ".png");if (imagePath != null) {final BmobFile bmobFile = new BmobFile(new File(imagePath));bmobFile.uploadblock(new UploadFileListener() {@Overridepublic void done(BmobException e) {if (e==null) {MyUser newUser=new MyUser();newUser.setImage(bmobFile.getFileUrl());newUser.update(currentUser.getObjectId(),new UpdateListener() {@Overridepublic void done(BmobException e) {if (e!=null)Log.i(TAG,e.getMessage());}});}else{Log.i(TAG,e.getMessage());}}});}}/*** 权限请求** @param requestCode* @param permissions* @param grantResults*/@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {} else {// 没有获取 到权限,从新请求,或者关闭appToast.makeText(this, "需要存储权限", Toast.LENGTH_SHORT).show();}}}

setting 的activity:

package com.example.yangzi.mvp_dev.ui.activity;import android.app.Activity;import android.content.DialogInterface;import android.content.Intent;import android.support.design.widget.TextInputLayout;import android.support.v4.view.GravityCompat;import android.support.v4.widget.DrawerLayout;import android.support.v7.app.AlertDialog;import android.support.v7.widget.Toolbar;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.Toast;import com.example.yangzi.mvp_dev.R;import com.example.yangzi.mvp_dev.base.BaseActivity;import com.example.yangzi.mvp_dev.bean.remote.MyUser;import com.example.mon.Constants;import com.example.yangzi.mvp_dev.utils.GlideCacheUtil;import com.example.yangzi.mvp_dev.utils.LogUtils;import com.example.yangzi.mvp_dev.utils.ProgressUtils;import com.example.yangzi.mvp_dev.utils.SnackbarUtils;import com.example.yangzi.mvp_dev.utils.ToastUtils;import com.example.yangzi.monItemLayout;import butterknife.BindView;import butterknife.OnClick;import cn.bmob.v3.BmobUser;import cn.bmob.v3.exception.BmobException;import cn.bmob.v3.listener.UpdateListener;/*** Created by linzihahaha on /12/30.*/public class SettingActivity extends BaseActivity {@BindView(R.id.toolbar)Toolbar toolbar;@BindView(R.id.cil_change)CommonItemLayout changeCL;@BindView(R.id.cil_forget)CommonItemLayout forgetCL;@BindView(R.id.cil_store)CommonItemLayout storeCL;@BindView(R.id.cil_sort)CommonItemLayout sortCL;@BindView(R.id.cil_pay)CommonItemLayout payCL;@BindView(R.id.cil_export)CommonItemLayout exportCL;private AlertDialog pwDialog;private AlertDialog cacheDialog;@Overrideprotected int getLayout() {return R.layout.activity_setting;}@Overrideprotected void initEventAndData() {//初始化Toolbartoolbar.setTitle("设置");setSupportActionBar(toolbar);getSupportActionBar().setDisplayHomeAsUpEnabled(true);toolbar.setNavigationOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//返回消息更新上个Activity数据//setResult(RESULT_OK, new Intent());finish();}});storeCL.setRightText(GlideCacheUtil.getInstance().getCacheSize(mContext));}/*** 监听点击事件* @param view*/@OnClick({R.id.cil_changePhone,R.id.cil_forget,R.id.cil_change,R.id.cil_store,R.id.cil_sort,R.id.cil_pay,R.id.cil_export,R.id.cil_aboutus})public void onViewClicked(final View view) {switch (view.getId()) {case R.id.cil_changePhone:verifyPhone(Constants.VERI_CHANGE_PHONE);break;case R.id.cil_change: //修改密码verifyPhone(Constants.VERI_CHANGE_PWD);break;case R.id.cil_forget: //忘记密码//startActivity(new Intent(this,ForgetPasswordActivity.class));showForgetPwDialog();break;case R.id.cil_store: //缓存showCacheDialog();break;case R.id.cil_aboutus:startActivity(new Intent(this, AboutActivity.class));break;default:break;}}private void verifyPhone(int index) {if (!MyUser.isLogin()) {Toast.makeText(getApplicationContext(), "请先登录!",Toast.LENGTH_SHORT).show();return;}String phonenunber=currentUser.getMobilePhoneNumber();if (phonenunber==null){Toast.makeText(getApplicationContext(), "请先绑定手机号!" ,Toast.LENGTH_SHORT).show();return;}Intent intent = new Intent();intent.putExtra("phoneNumber",phonenunber);intent.putExtra("index",""+index);intent.setClass(this, VerifyPhoneActivity.class);startActivityForResult(intent,index);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == Constants.VERI_CHANGE_PWD && resultCode == Activity.RESULT_OK) {showChangePwdDialog();}else if (requestCode == Constants.VERI_CHANGE_PHONE && resultCode == Activity.RESULT_OK) {Log.v(LogUtils.filename(new Exception()),LogUtils.funAndLine(new Exception())+data.getStringExtra("phone"));changePhone(data.getStringExtra("phone"));}}/*** 显示忘记密码对话框*/public void showForgetPwDialog() {final EditText editText = new EditText(mContext);editText.setHint("请输入注册邮箱");//弹出输入框new AlertDialog.Builder(this).setTitle("忘记密码").setView(editText).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {String input = editText.getText().toString();if (input.equals("")) {SnackbarUtils.show(mContext, "内容不能为空!");}else{//找回密码BmobUser.resetPasswordByEmail(input, new UpdateListener() {@Overridepublic void done(BmobException e) {if(e==null){ToastUtils.show(mContext,"重置密码请求成功,请到邮箱进行密码重置操作");}else{ToastUtils.show(mContext,"失败:" + e.getMessage());}}});}}}).setNegativeButton("取消", null).show();}/*** 显示修改密码对话框*/public void showChangePwdDialog() {final LinearLayout layout=new LinearLayout(mContext);//加载布局View view= LayoutInflater.from(mContext).inflate(R.layout.dialog_change_password,layout,false);TextInputLayout til=(TextInputLayout)view.findViewById(R.id.change_til_password);TextInputLayout til1=(TextInputLayout)view.findViewById(R.id.change_til_repassword);final EditText editText = til.getEditText();final EditText editText1 = til1.getEditText();//加入视图layout.addView(view);if (pwDialog == null) {pwDialog = new AlertDialog.Builder(this).setTitle("修改密码").setView(layout).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {String input = editText.getText().toString();String input1 = editText1.getText().toString();if (input.equals("")||input1.equals("")) {Toast.makeText(getApplicationContext(), "不能为空!" + input,Toast.LENGTH_SHORT).show();}else if(input.equals(input1)){//修改密码changePw(input);} else {Toast.makeText(mContext,"两次输入不一致", Toast.LENGTH_LONG).show();}}}).setNegativeButton("取消", null).create();}if (!pwDialog.isShowing()) {pwDialog.show();}}/*** 显示清除缓存对话框*/public void showCacheDialog() {if (cacheDialog == null) {cacheDialog = new AlertDialog.Builder(this).setTitle("清除缓存").setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {GlideCacheUtil.getInstance().clearImageDiskCache(mContext);}}).setNegativeButton("取消", null).create();}if (!cacheDialog.isShowing()) {cacheDialog.show();}}/*** 更新用户密码*/public void changePw(String password) {if (currentUser == null)return;ProgressUtils.show(mContext, "正在修改...");currentUser.setPassword(password);currentUser.update(new UpdateListener() {@Overridepublic void done(BmobException e) {ProgressUtils.dismiss();if (e!=null){ToastUtils.show(mContext,"修改失败"+e.getMessage());Log.v(LogUtils.filename(new Exception()), LogUtils.funAndLine(new Exception()) +currentUser.getUsername()+ e.getMessage());} else{ToastUtils.show(mContext,"修改成功");}}});}/*** 更新用户手机号*/public void changePhone(String phone) {if (currentUser == null)return;ProgressUtils.show(mContext, "正在修改...");currentUser.setMobilePhoneNumber(phone);currentUser.update(new UpdateListener() {@Overridepublic void done(BmobException e) {ProgressUtils.dismiss();if (e!=null){ToastUtils.show(mContext,"修改失败"+e.getMessage());Log.v(LogUtils.filename(new Exception()), LogUtils.funAndLine(new Exception()) +currentUser.getUsername()+ e.getMessage());} else{ToastUtils.show(mContext,"修改成功");}}});}}

还有mainActivity:

package com.example.yangzi.mvp_dev.ui.activity;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.ActivityInfo;import android.os.Build;import android.support.annotation.NonNull;import android.support.annotation.RequiresApi;import android.support.design.widget.NavigationView;import android.support.v4.view.GravityCompat;import android.support.v4.widget.DrawerLayout;import android.support.v7.app.ActionBarDrawerToggle;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.Toolbar;import android.util.Log;import android.view.MenuItem;import android.view.View;import android.view.Window;import android.widget.ImageView;import android.widget.TextView;import com.bumptech.glide.Glide;import com.example.yangzi.mvp_dev.R;import com.example.yangzi.mvp_dev.base.BaseActivity;import com.example.yangzi.mvp_dev.bean.remote.MyUser;import com.example.yangzi.mvp_dev.utils.LogUtils;import com.example.yangzi.mvp_dev.utils.ThemeManager;import butterknife.BindView;import butterknife.ButterKnife;import butterknife.OnClick;import cn.bmob.v3.BmobUser;public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener{@BindView(R.id.toolbar)android.support.v7.widget.Toolbar toolbar;@BindView(R.id.drawer_layout)DrawerLayout drawer;@BindView(R.id.nav_view)NavigationView navigationView;private View drawerHeader;private ImageView drawerIv;private TextView drawerTvAccount, drawerTvMail;protected static final int USERINFOACTIVITY_CODE = 0;protected static final int LOGINACTIVITY_CODE = 1;@Overrideprotected int getLayout() {return R.layout.activity_main;}@Overrideprotected void initEventAndData() {//初始化Toolbartoolbar.setTitle("MVP");setSupportActionBar(toolbar);ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);drawer.setDrawerListener(toggle);toggle.syncState();if (navigationView.getHeaderCount()>0) {drawerHeader =navigationView.getHeaderView(0);}else {drawerHeader = navigationView.inflateHeaderView(R.layout.drawer_header);}drawerIv = (ImageView) drawerHeader.findViewById(R.id.drawer_iv);drawerTvAccount = (TextView) drawerHeader.findViewById(R.id.drawer_tv_name);drawerTvMail = (TextView) drawerHeader.findViewById(R.id.drawer_tv_mail);//监听点击登陆事件drawerHeader.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);drawer.closeDrawer(GravityCompat.START);if (currentUser==null) {//用户id为0表示未有用户登陆startActivityForResult(new Intent(MainActivity.this, LoginActivity.class), LOGINACTIVITY_CODE);} else {//进入账户中心startActivityForResult(new Intent(MainActivity.this, UserInfoActivity.class), USERINFOACTIVITY_CODE);}}});//设置头部账户setDrawerHeaderAccount();//监听侧滑菜单navigationView.setNavigationItemSelectedListener(this);}/*** 设置DrawerHeader的用户信息*/public void setDrawerHeaderAccount() {currentUser= BmobUser.getCurrentUser(MyUser.class);//获取当前用户if (currentUser != null) {drawerTvAccount.setText(currentUser.getUsername());drawerTvMail.setText(currentUser.getMobilePhoneNumber());if (currentUser.getImage()!=null) Glide.with(mContext).load(currentUser.getImage()).into(drawerIv);}else{drawerTvAccount.setText("账号");drawerTvMail.setText("点我登陆");drawerIv.setImageResource(R.mipmap.ic_def_icon);}}/*** 监听Drawer*/@Overridepublic void onBackPressed() {DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);if (drawer.isDrawerOpen(GravityCompat.START)) {drawer.closeDrawer(GravityCompat.START);} else {super.onBackPressed();}}/*** 监听点击事件 R.id.drawer_tv_name,R.id.drawer_tv_mail** @param view*/@OnClick({})public void onClick(View view) {switch (view.getId()) {default:break;}}/*** 监听Activity返回值f** @param requestCode* @param resultCode* @param data*/@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {switch (requestCode) {case USERINFOACTIVITY_CODE:setDrawerHeaderAccount();break;case LOGINACTIVITY_CODE:setDrawerHeaderAccount();break;}}}/*** 显示修改主题色 Dialog*/private void showUpdateThemeDialog() {final String[] themes = ThemeManager.getInstance().getThemes();new AlertDialog.Builder(mContext).setTitle("选择主题").setItems(themes, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {ThemeManager.getInstance().setTheme(mContext, themes[which]);}}).create().show();}@Overridepublic boolean onNavigationItemSelected(@NonNull MenuItem item) {int id = item.getItemId();if (id == R.id.nav_exit) {//退出登陆currentUser= BmobUser.getCurrentUser(MyUser.class);if (currentUser==null){new AlertDialog.Builder(mContext).setTitle("当前账户未登录").show();}else {//退出登陆new AlertDialog.Builder(mContext).setTitle("是否退出当前账户").setNegativeButton("取消", null).setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {MyUser.logOut();//清除本地数据//LocalRepository.getInstance().deleteAllBills();//刷新账户数据//setDrawerHeaderAccount();initEventAndData();}}).show();}} else if (id == R.id.nav_theme) {//主题showUpdateThemeDialog();}else if (id == R.id.nav_setting) { //设置startActivity(new Intent(this, SettingActivity.class));}return false;}}

还有 验证码验证的Activity:

package com.example.yangzi.mvp_dev.ui.activity;import android.app.Activity;import android.content.Intent;import android.support.design.widget.TextInputLayout;import android.text.Editable;import android.text.TextWatcher;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import com.example.yangzi.mvp_dev.R;import com.example.yangzi.mvp_dev.base.BaseActivity;import com.example.yangzi.mvp_dev.bean.remote.MyUser;import com.example.yangzi.mvp_dev.mvp.presenter.Imp.UserLogPresenterImp;import com.example.yangzi.mvp_dev.mvp.presenter.UserLogPresenter;import com.example.yangzi.mvp_dev.mvp.view.UserLogView;import com.example.yangzi.mvp_dev.utils.LogUtils;import com.example.yangzi.mvp_dev.utils.ProgressUtils;import com.example.yangzi.mvp_dev.utils.RegexUtils;import com.example.yangzi.mvp_dev.utils.SnackbarUtils;import com.example.yangzi.mvp_dev.utils.ToastUtils;import com.example.yangzi.mvp_dev.widget.OwlView;import com.example.yangzi.mvp_dev.widget.VerifyCodeButton;import java.util.List;import butterknife.BindView;import butterknife.OnClick;import butterknife.OnFocusChange;import cn.bmob.v3.BmobQuery;import cn.bmob.v3.BmobSMS;import cn.bmob.v3.exception.BmobException;import cn.bmob.v3.listener.FindListener;import cn.bmob.v3.listener.QueryListener;import cn.bmob.v3.listener.UpdateListener;/*** Created by zhouas666 on /12/8.*/public class VerifyPhoneActivity extends BaseActivity implements UserLogView {String phonenum;boolean isphoneExisted= false;@BindView(R.id.verify_et_phone)TextInputLayout phone;@BindView(R.id.verify_text)TextView phonetext;@BindView(R.id.verify_get_code)TextInputLayout getCode;@BindView(R.id.btn_verify_get_code)VerifyCodeButton getcodeBtn;@BindView(R.id.verify_btn_verify)Button loginBtn;private EditText mEdtPhone;private EditText mEdtCode;@Overrideprotected int getLayout() {return R.layout.activity_verify_phone;}@Overrideprotected void initEventAndData() {phone.setVisibility(View.GONE);mEdtPhone = phone.getEditText();Intent intent = getIntent();phonenum = intent.getStringExtra("phoneNumber");if (intent.getStringExtra("index").equals("1001")) {phone.setVisibility(View.VISIBLE); //如果是修改手机号,验证新输入的手机号} else {phonetext.setText("(" + phonenum.substring(0, 3) + "****" + phonenum.substring(7, 11) + ")"); //如果是其他,验证传进的手机号}mEdtCode = getCode.getEditText();mEdtCode.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {String code = charSequence.toString();if (!RegexUtils.checkCode(code)) {getCode.setError("请输入正确的验证码");} else {getCode.setErrorEnabled(false);}}@Overridepublic void afterTextChanged(Editable editable) {}});}/*** 监听点击事件** @param view*/@OnClick({R.id.btn_verify_get_code, R.id.verify_btn_verify})protected void onClick(View view) {switch (view.getId()) {case R.id.btn_verify_get_code: // 获取验证码getCode();break;case R.id.verify_btn_verify: //buttonverify(); //登陆break;default:break;}}private void getCode() {if(phone.isShown()) phonenum = mEdtPhone.getText().toString();requestSMScodeFromBmob(phonenum);}/*** 请求验证码* @param phone_number 手机号* @param template_name 验证码模板名称* @param listener 回调*//*** TODO template 如果是自定义短信模板,此处替换为你在控制台设置的自定义短信模板名称;如果没有对应的自定义短信模板,则使用默认短信模板。*/public void requestSMScodeFromBmob(String phone) {getcodeBtn.start();Log.v(LogUtils.filename(new Exception()),LogUtils.funAndLine(new Exception())+phone);BmobSMS.requestSMSCode(phone, "register", new QueryListener<Integer>() {@Overridepublic void done(Integer smsId, BmobException e) {if (e == null) {Toast.makeText(mContext, "发送验证码成功,短信ID:" + smsId + "\n", Toast.LENGTH_SHORT).show();} else {Toast.makeText(mContext, "发送验证码失败:" + e.getErrorCode() + "-" + e.getMessage() + "\n", Toast.LENGTH_SHORT).show();}}});}/*** 执行验证动作*/public void verify() {if(phone.isShown()) phonenum = mEdtPhone.getText().toString();String code = mEdtCode.getText().toString();Log.v(LogUtils.filename(new Exception()),LogUtils.funAndLine(new Exception())+phonenum);veriflySMSCode(phonenum,code);}private void veriflySMSCode(final String phonenumber,final String code) {BmobSMS.verifySmsCode(phonenumber, code, new UpdateListener() {@Overridepublic void done(BmobException e) {if (e == null) {ToastUtils.show(mContext, "验证码验证成功");ProgressUtils.dismiss();Intent intent= new Intent();intent.putExtra("phone",phonenum);setResult(Activity.RESULT_OK, intent);//返回上一个activityfinish();}else{ToastUtils.show(mContext, "验证失败"+phonenumber+code);}}});}@Overridepublic void loadDataSuccess(MyUser tData) {}@Overridepublic void loadDataError(Throwable throwable) {}}

其他的一些我就不一一贴出了。

可以进入下面链接下载完整demo。/download/linzihahaha/10887958

另外由于bmob的短信发送是需要收费的,所以真正是无法发送短信成功的,如果有需要,可以留言找我要ID,替换后,就能收到短信验证码了。

本文实例大的UI 结构设计参考/p/5661102867,侵删。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。