////////////////////2016/05/14////////////////////////
/////////////////////by xbw//////////////////////////////
/////////////////eclipse api 21/////////////////////
快期末考试了,把之前做的项目整理一下,分享点demo,基于mob短信验证的账号注册demo,那个mob的key的注册直接去mob官网注册就好了,不多说了,先看一下效果图。
首先在mob官网下载短信验证sdk,咱这有demo,一会贴出来,直接复制demo里的sdk就好了,
首先在res文件中新建raw文件夹,把libs文件复制进去,再把smssdk_errors.xml文件复制到values文件夹中,
复制这几个文件到lib文件夹下,好了,开始敲代码,首先去AndroidManifest.xml文件下注册权限,
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xbw.login" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.FLASHLIGHT" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RESTART_PACKAGES" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" /> <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> <uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BATTERY_STATS" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Light.NoTitleBar" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.mob.tools.MobUIShell" android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:windowSoftInputMode="stateHidden|adjustResize" /> </application> </manifest>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#373447" > <ImageView android:id="@+id/user_logo" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:contentDescription="@string/app_name" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/userNameTxt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/user_logo" android:layout_centerHorizontal="true" android:layout_marginTop="5dp" android:text="XBW" android:textColor="#CEC9E7" android:textSize="16sp" /> <LinearLayout android:id="@+id/accountLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/userNameTxt" android:layout_centerHorizontal="true" android:layout_marginTop="30dp" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_user" /> <EditText android:id="@+id/chat_register_username" android:layout_width="240dp" android:layout_height="wrap_content" android:background="@null" android:hint="手机号" android:padding="10dp" android:singleLine="true" android:textColor="#CEC9E7" android:textSize="16sp" /> </LinearLayout> <View android:id="@+id/line3" android:layout_width="240dp" android:layout_height="1dp" android:layout_below="@id/accountLayout" android:layout_centerHorizontal="true" android:background="#CEC9E7" /> <LinearLayout android:id="@+id/accountLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/line3" android:layout_centerHorizontal="true" android:layout_marginTop="35dp" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_user" /> <EditText android:id="@+id/chat_register_code" android:layout_width="240dp" android:layout_height="wrap_content" android:background="@null" android:hint="短信验证码" android:padding="10dp" android:singleLine="true" android:textColor="#CEC9E7" android:textSize="16sp" /> </LinearLayout> <View android:id="@+id/line1" android:layout_width="240dp" android:layout_height="1dp" android:layout_below="@id/accountLayout2" android:layout_centerHorizontal="true" android:background="#CEC9E7" /> <LinearLayout android:id="@+id/pwdLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/line1" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_pwd" /> <EditText android:id="@+id/chat_register_password" android:layout_width="204dp" android:layout_height="wrap_content" android:background="@null" android:hint="密码(最少6位)" android:inputType="textPassword" android:padding="10dp" android:singleLine="true" android:textColor="#CEC9E7" android:textSize="16sp" /> <CheckBox android:id="@+id/chat_register_password_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="5dp" android:button="@drawable/password_checkbox" /> </LinearLayout> <View android:id="@+id/line2" android:layout_width="240dp" android:layout_height="1dp" android:layout_below="@id/pwdLayout" android:layout_centerHorizontal="true" android:background="#CEC9E7" /> <LinearLayout android:id="@+id/pwdLayoutre" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/line2" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_pwd" /> <EditText android:id="@+id/chat_register_password2" android:layout_width="204dp" android:layout_height="wrap_content" android:background="@null" android:hint="确认密码" android:inputType="textPassword" android:padding="10dp" android:singleLine="true" android:textColor="#CEC9E7" android:textSize="16sp" /> <CheckBox android:id="@+id/chat_register_password_checkbox2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="5dp" android:button="@drawable/password_checkbox" /> </LinearLayout> <View android:id="@+id/line4" android:layout_width="240dp" android:layout_height="1dp" android:layout_below="@id/pwdLayoutre" android:layout_centerHorizontal="true" android:background="#CEC9E7" /> <Button android:id="@+id/chat_register_signup_btn" android:layout_width="240dp" android:layout_height="wrap_content" android:layout_alignLeft="@+id/line2" android:layout_alignParentBottom="true" android:layout_marginBottom="26dp" android:background="#312E3F" android:padding="10dp" android:text="注册" android:textColor="#CEC9E7" android:textSize="20dp" android:textStyle="bold" /> <Button android:id="@+id/chat_register_sendmsg_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/line3" android:layout_alignRight="@+id/line3" android:layout_below="@+id/line3" android:layout_marginTop="7dp" android:background="@drawable/btn_long_red" android:text="发送短信验证码" /> </RelativeLayout>
短信验证我们用到了自动填充短信验证码,还有发送验证码后60秒短信倒计时;
我们需要写两个类
SmsContent.java 自动填充短信验证码
package com.xbw.login; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.app.Activity; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.widget.EditText; public class SmsContent extends ContentObserver { public static final String SMS_URI_INBOX = "content://sms/inbox"; private Activity activity = null; private String smsContent = ""; private EditText verifyText = null; public SmsContent(Activity activity, Handler handler, EditText verifyText) { super(handler); this.activity = activity; this.verifyText = verifyText; } @SuppressWarnings("deprecation") @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Cursor cursor = null;// 光标 // 读取收件箱中指定号码的短信 cursor = activity.managedQuery(Uri.parse(SMS_URI_INBOX), new String[] { "_id", "address", "body", "read" }, "address=? and read=?", new String[] { "106571207117008", "0" }, "date desc");//mob短信验证号码 if (cursor != null) {// 如果短信为未读模式 cursor.moveToFirst(); if (cursor.moveToFirst()) { String smsbody = cursor .getString(cursor.getColumnIndex("body")); System.out.println("smsbody=======================" + smsbody); String pattern = "[1-9]\\d*"; Pattern p = Pattern.compile(pattern); Matcher m = p.matcher(smsbody.toString()); ArrayList al =new ArrayList(); while(m.find()) { al.add(m.group(0)); } if(!al.isEmpty()) verifyText.setText(al.get(0).toString()); } } } }
package com.xbw.login; import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.Color; import android.os.CountDownTimer; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; import android.widget.Button; public class TimeCountUtil extends CountDownTimer { private Activity mActivity; private Button btn;//按钮 // 在这个构造方法里需要传入三个参数,一个是Activity,一个是总的时间millisInFuture,一个是countDownInterval,然后就是你在哪个按钮上做这个是,就把这个按钮传过来就可以了 public TimeCountUtil( Activity mActivity,long millisInFuture, long countDownInterval,Button btn) { super(millisInFuture, countDownInterval); this.mActivity = mActivity; this.btn =btn; } @SuppressLint("NewApi") @Override public void onTick(long millisUntilFinished) { btn.setClickable(false);//设置不能点击 btn.setText(millisUntilFinished / 1000 + "秒后可重新发送");//设置倒计时时间 //设置按钮为灰色,这时是不能点击的 btn.setBackground(mActivity.getResources().getDrawable(R.drawable.btn_long_white)); Spannable span = new SpannableString(btn.getText().toString());//获取按钮的文字 span.setSpan(new ForegroundColorSpan(Color.RED), 0, 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);//讲倒计时时间显示为红色 btn.setText(span); } @SuppressLint("NewApi") @Override public void onFinish() { btn.setText("重新获取验证码"); btn.setClickable(true);//重新获得点击 btn.setBackground(mActivity.getResources().getDrawable(R.drawable.btn_long_red));//还原背景色 } }
package com.xbw.login; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.text.method.HideReturnsTransformationMethod; import android.text.method.PasswordTransformationMethod; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import cn.smssdk.EventHandler; import cn.smssdk.SMSSDK; public class MainActivity extends Activity { private EditText mUsernameET; private EditText mPasswordET; private EditText mCodeET; private EditText mPasswordET2; private Button mSendmsgBtn; private Button mSignupBtn; private CheckBox mPasswordCB; private CheckBox mPasswordCB2; private String phone_number = ""; private boolean success = false; Dialog dialog; SmsContent content; // private SmsReceiver smsReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow() .addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);// 沉浸式状态栏 getWindow().addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);// 沉浸式状态栏 setContentView(R.layout.activity_register); initView(); SMSSDK.initSDK(this, mob_APPKEY, mob_APPSECRET);//mob的key EventHandler eh = new EventHandler() { @Override public void afterEvent(int event, int result, Object data) { Message msg = new Message(); msg.arg1 = event; msg.arg2 = result; msg.obj = data; handlersms.sendMessage(msg); } }; SMSSDK.registerEventHandler(eh); } @SuppressLint("NewApi") private void initView() { mUsernameET = (EditText) findViewById(R.id.chat_register_username); mPasswordET = (EditText) findViewById(R.id.chat_register_password); mPasswordET2 = (EditText) findViewById(R.id.chat_register_password2); mCodeET = (EditText) findViewById(R.id.chat_register_code); mSendmsgBtn = (Button) findViewById(R.id.chat_register_sendmsg_btn); mSignupBtn = (Button) findViewById(R.id.chat_register_signup_btn); mPasswordCB = (CheckBox) findViewById(R.id.chat_register_password_checkbox); mPasswordCB2 = (CheckBox) findViewById(R.id.chat_register_password_checkbox2); mUsernameET.addTextChangedListener(myWatchers); mCodeET.addTextChangedListener(myWatcher); mPasswordCB.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton arg0, boolean arg1) { // TODO Auto-generated method stub if (arg1) { mPasswordCB.setChecked(true); mPasswordET .setTransformationMethod(HideReturnsTransformationMethod .getInstance()); } else { mPasswordCB.setChecked(false); mPasswordET .setTransformationMethod(PasswordTransformationMethod .getInstance()); } } }); mPasswordCB2.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton arg0, boolean arg1) { // TODO Auto-generated method stub if (arg1) { mPasswordCB2.setChecked(true); mPasswordET2 .setTransformationMethod(HideReturnsTransformationMethod .getInstance()); } else { mPasswordCB2.setChecked(false); mPasswordET2 .setTransformationMethod(PasswordTransformationMethod .getInstance()); } } }); mSendmsgBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO 自动生成的方法存根 if (TextUtils.isEmpty(mUsernameET.getText().toString())) { Toast.makeText(getApplicationContext(), "手机号码不能为空", 1) .show(); } else if (!judgephone(mUsernameET.getText().toString())) { Toast.makeText(getApplicationContext(), "请输入正确的手机号码", 1) .show(); } else { new Thread() { public void run() { try { SMSSDK.getVerificationCode("86", mUsernameET .getText().toString()); success = true; } catch (Exception e) { e.printStackTrace(); } finally { } } }.start(); // ////////////////////////////////////////////////////////////////////////////////// } } }); mSignupBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub final String userName = mUsernameET.getText().toString().trim(); final String password = mPasswordET.getText().toString().trim(); final String password2 = mPasswordET2.getText().toString() .trim(); final String code = mCodeET.getText().toString().trim(); if (TextUtils.isEmpty(userName)) { Toast.makeText(getApplicationContext(), "请输入手机号", Toast.LENGTH_SHORT).show(); } else if (!judgephone(userName)) { Toast.makeText(getApplicationContext(), "请输入正确的手机号", Toast.LENGTH_SHORT).show(); } else if (TextUtils.isEmpty(password)) { Toast.makeText(getApplicationContext(), "请输入密码", Toast.LENGTH_SHORT).show(); } else if (password.length() < 6) { Toast.makeText(getApplicationContext(), "密码长度不小于6位", Toast.LENGTH_SHORT).show(); } else if (TextUtils.isEmpty(password2)) { Toast.makeText(getApplicationContext(), "请确认输入密码", Toast.LENGTH_SHORT).show(); } else if (!password.equals(password2)) { Toast.makeText(getApplicationContext(), "两次密码输入不一致", Toast.LENGTH_SHORT).show(); } else { // 插入数据库 } } }); mSignupBtn.setClickable(false); mSignupBtn.setBackground(MainActivity.this.getResources().getDrawable( R.color.sign_up_btn_normal)); mSendmsgBtn.setText("发送验证码"); mSendmsgBtn.setClickable(false); mSendmsgBtn.setBackground(this.getResources().getDrawable( R.drawable.btn_long_white)); } Handler handlersms = new Handler() { @SuppressLint("NewApi") @SuppressWarnings("deprecation") @Override public void handleMessage(Message msg) { super.handleMessage(msg); int event = msg.arg1; int result = msg.arg2; Object data = msg.obj; Log.e("event", "event=" + event); if (result == SMSSDK.RESULT_COMPLETE) { if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) { if (result == SMSSDK.RESULT_COMPLETE) { Toast.makeText(getApplicationContext(), "短信验证成功", Toast.LENGTH_SHORT).show(); mSignupBtn.setBackground(MainActivity.this .getResources().getDrawable( R.color.sign_up_btn_press)); mSignupBtn.setClickable(true); } } else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) { Toast.makeText(getApplicationContext(), "验证码已经发送", Toast.LENGTH_SHORT).show(); TimeCountUtil timeCountUtil = new TimeCountUtil( MainActivity.this, 60000, 1000, mSendmsgBtn); timeCountUtil.start(); // smsReceiver = new SmsReceiver(); // registerBroadcastReceiver(); content = new SmsContent(MainActivity.this, new Handler(), mCodeET); // 注册短信变化监听 getContentResolver().registerContentObserver( Uri.parse("content://sms/"), true, content); // dialog.dismiss(); } else if (event == SMSSDK.RESULT_ERROR) { Toast.makeText(getApplicationContext(), "------", 1000) .show(); } } else { ((Throwable) data).printStackTrace(); Toast.makeText(getApplicationContext(), "错误" + data, 10000) .show(); } dialog.dismiss(); } }; TextWatcher myWatcher = new TextWatcher() { @Override public void afterTextChanged(Editable s) { if (mCodeET.getText().length() == 4 && judgephone(mUsernameET.getText().toString()) && success) { new Thread() { public void run() { try { SMSSDK.submitVerificationCode("86", mUsernameET .getText().toString(), mCodeET.getText() .toString()); } catch (Exception e) { e.printStackTrace(); } finally { } } }.start(); } // ////////////////////////////////////////////////////////////////////////////////// } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO 自动生成的方法存根 } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO 自动生成的方法存根 } }; TextWatcher myWatchers = new TextWatcher() { @SuppressLint("NewApi") @Override public void afterTextChanged(Editable s) { if (mUsernameET.getText().length() == 11) { if (judgephone(mUsernameET.getText().toString())) { // 从数据库判断此账号是否存在 } } else { success = false; mSignupBtn.setClickable(false); mSignupBtn.setBackground(MainActivity.this.getResources() .getDrawable(R.color.sign_up_btn_normal)); } // ////////////////////////////////////////////////////////////////////////////////// } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO 自动生成的方法存根 } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO 自动生成的方法存根 } }; public boolean judgephone(String phone) { String str = ""; str = phone; String pattern = "(13\\d|14[57]|15[^4,\\D]|17[678]|18\\d)\\d{8}|170[059]\\d{7}"; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(str); return m.matches(); } public void back(View view) { finish(); } @Override protected void onDestroy() { super.onDestroy(); SMSSDK.unregisterAllEventHandler(); if (content != null) this.getContentResolver().unregisterContentObserver(content); // stopBroadcastReceiver(); } }最后的正则表达式匹配手机号多余了,mob的自带了,数据库还需要自己搭建,这就不贴了;
demo传送门