Android版QQ的实现

1、首先设置好基本的布局和页面设置;

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

Android版QQ的实现

2、建立SQLite数据库创建用户的信息表;完成用户的登录和注册功能;

  • 首先创建一个数据库类继承SQLiteOpenHelper
package com.example.myapplication.Database;

import android.database.sqlite.SQLiteOpenHelper;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
/**
 * ClassName:DatabaseHelper
 * Package:com.example.myapplication.Database
 * Description: meet 985&ta
 *创建一个数据库的类;
 * @Data:2021/11/08 16:47
 * @Author:灿灿睡醒了
 */
public class DatabaseHelper extends SQLiteOpenHelper {

    private static final int VERSION = 3;//数据库版本号
    private static String DB_NAME="user";//数据库名称
    private static String TAG="DatabaseHelper";//数据库名称

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, VERSION);
    }

    //当第一次建库的时候,调用该方法
    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建数据库的时候把用户表创建好
        String sql = "create table user(id int,password varchar(20))";
        db.execSQL(sql);

        Log.i(TAG, "创建数据库.....");
    }

    //当更新数据库版本号的时候就会执行该方法
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        Log.i(TAG, "更新数据库.....");
    }
}
package com.example.myapplication.Shixian;

import java.io.Serializable;

/**
 * ClassName:User
 * Package:com.example.myapplication.Shixian
 * Description: meet 985&ta
 * 在User文件中声明要用到的表列名的变量,并对其添加get&&set方法:
 * 完成QQ的注册功能;
 * @Data:2021/11/07 20:18
 * @Author:灿灿睡醒了
 */

//用户表的设置;
public class User implements Serializable {

    //用户的信息表只包括两个信息;
    private static String id;//用户的账号
    private static String password;//用户密码

    public User() {
        super();
        // TODO Auto-generated constructor stub
    }

    public User(String id,String password) {
        super();
        this.id = id;
        this.password = password;
    }

    public static String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public static String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", password=" + password + "]";
    }

}

增删改查UserDao.java

package com.example.myapplication.Database;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.View;

import com.example.myapplication.Shixian.User;

/**
 * ClassName:Dao
 * Package:com.example.myapplication.Database
 * Description: meet 985&ta
 * 此类用来创建用户数据库以及增删改查;
 * @Data:2021/11/08 17:08
 * @Author:灿灿睡醒了
 */
public class UserDao {
    private final DatabaseHelper databaseHelper;//设置为一个静态变量;
    private  SQLiteDatabase db;//外部全局变量;

    public UserDao(Context context) {
        //创建数据库;
        databaseHelper = new DatabaseHelper(context);
    }

    //往用户表添加数据
    public void insert( ) {
        //打开该数据库;
        db = databaseHelper.getWritableDatabase();

        //在这里引入表名;插入字段和数据;
        String sql = "insert into " + databaseHelper.TABLENAME + "(id,password)values(?,?)";
        Object obj[]= new Object[]{User.getId(), User.getPassword()};
        db.execSQL(sql, obj);
        db.close();
        Log.i("RegisterActivity", "添加了一个用户记录");
    }

//往用户表删除数据
    public void delete( ) {
        //打开该数据库;
        db = databaseHelper.getWritableDatabase();

        String sql = "delete from " + databaseHelper.TABLENAME + "where id=?";
        Object obj[]= new Object[]{User.getId()};
        db.execSQL(sql,obj);
        db.close();
    }

    //更改数据;
    public void update(String id,String password){
        //打开该数据库;
        db = databaseHelper.getWritableDatabase();

        ContentValues contentValues = new ContentValues();
        contentValues.put("password", password);
        //参数1:表名 参数2:修改的值 参数三:查询条件 参数4:查询条件需要的参数
        //根据id来修改password;
        db.update("user", contentValues, "id=?", new String[]{id});
        db.close();
        Log.i("ForgetActivity","修改密码成功");

    }

    //判断数据库是否存在该账号
    public boolean find(String id){
        //打开该数据库;
        db = databaseHelper.getWritableDatabase();
        //默认没有该数据
        boolean flag=false;
        //查询所有号码(表名,查询账号,查询条件没有--null)
        Cursor cursor=db.query("users",new String[]{"id"},null,null,null,null,null);
        //如果游标能往下移动
        while (cursor.moveToNext()){
            //遍历Cursor对象,跟传入的id进行比较,如果相同就返回true,说明数据库存在该数据
            if(id.equals(cursor.getString(0))){
                flag=true;
            }
        }
        /*
        一定要关闭游标,回收游标对象
        */
        cursor.close();
        db.close();
        return flag;
    }
}
DatabaseHelper.java类创建数据库实验对象:
package com.example.myapplication.Database;

import android.database.sqlite.SQLiteOpenHelper;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
/**
 * ClassName:DatabaseHelper
 * Package:com.example.myapplication.Database
 * Description: meet 985&ta
 *创建一个数据库的类;
 * @Data:2021/11/08 16:47
 * @Author:灿灿睡醒了
 */
public class DatabaseHelper extends SQLiteOpenHelper {

    private static final int VERSION = 3;//数据库版本号
    private static String DB_NAME="USER";//数据库名称
    private static String TAG="DatabaseHelper";//数据库名称
    public static String TABLENAME="users";//表名称

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, VERSION);
    }

    //当第一次建库的时候,调用该方法
    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建数据库的时候把用户表创建好
        String sql = "create table "+TABLENAME+"(id varchar(20),password varchar(20))";
        db.execSQL(sql);

        Log.i(TAG, "创建数据库.....");
    }

    //当更新数据库版本号的时候就会执行该方法
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        Log.i(TAG, "更新数据库.....");
        //先不使用此功能;
    }
}

测试数据库:可以自动生成测试类
* 右键–>go to–>Test

实现登录验证功能LoginActivity.java和UserDao.java:

*
添加手机验证码功能时:
* 注册页面:mob.com/mobService/sms
* 具体验证码步骤的实现
* Android中实现手机获取验证码登录的功能_季风__的博客-CSDN博客_android手机验证码登录
* Android proguard文件路径 – 简书 混淆文件
* 安卓 实现获取手机验证码登录功能_A赴野的博客-CSDN博客
* 遇到的一些问题:
①显示你的NDK找不到,打开File->Project Structure->SDK Location 在Android NDK location一栏点击下载,下载完成后clean project再build project就可以了。
解决方法:就是在settings里面找到AndroidSDK–>SDKTools自动下载相应的版本
②在注册应用时找不到MD5密钥:
*

C:\WINDOWS\system32>L:

L:\>cd L:\Androidexe\jre\bin

L:\Androidexe\jre\bin>keytool -list -v -keystore debug.keystore
keytool 错误: java.lang.Exception: 密钥库文件不存在: debug.keystore
java.lang.Exception: 密钥库文件不存在: debug.keystore
        at sun.security.tools.keytool.Main.doCommands(Main.java:768)
        at sun.security.tools.keytool.Main.run(Main.java:366)
        at sun.security.tools.keytool.Main.main(Main.java:359)

L:\Androidexe\jre\bin>cd L:\Androidexe\jre\jre\bin\

L:\Androidexe\jre\jre\bin>keytool -list -v -keystore debug.keystore
keytool 错误: java.lang.Exception: 密钥库文件不存在: debug.keystore
java.lang.Exception: 密钥库文件不存在: debug.keystore
        at sun.security.tools.keytool.Main.doCommands(Main.java:768)
        at sun.security.tools.keytool.Main.run(Main.java:366)
        at sun.security.tools.keytool.Main.main(Main.java:359)

Android版QQ的实现
别名: androiddebugkey
创建日期: 2021-11-11
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=wu, OU=hnust, O=hnust, L=hunan, ST=hunan, C=china
发布者: CN=wu, OU=hnust, O=hnust, L=hunan, ST=hunan, C=china
序列号: 2d563662
有效期为 Thu Nov 11 09:32:14 CST 2021 至 Mon Mar 29 09:32:14 CST 2049
证书指纹:
         MD5:  CC:C5:0C:B1:69:E2:0D:A1:4C:90:3F:02:2A:7B:05:74
         SHA1: 8F:E7:F7:06:20:57:3D:EA:09:99:B3:35:6D:FC:8C:EB:5F:A3:27:CD
         SHA256: AC:8A:47:6A:B5:DC:14:AC:65:DD:86:26:7D:6B:9B:72:CB:F0:E7:D7:7F:82:35:D4:AB:83:24:E7:3E:CC:CF:83
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3

扩展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 01 76 DB 69 19 C6 33 22   D2 B5 B2 5E 08 A4 A1 99  .v.i..3"...^....

0010: A1 4F 4B 9B                                        .OK.

]
]
  • 验证码功能代码段1
package com.example.myapplication.widget;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.myapplication.R;
import com.mob.MobSDK;

import cn.smssdk.EventHandler;
import cn.smssdk.SMSSDK;

public class PhoneActivity extends AppCompatActivity implements View.OnClickListener {
    String APPKEY = "34afc2be232e8";
    String APPSECRETE = "09dc75fb83ae9d913ac3b5b8156ffc7d";

    // 手机号输入框
    private EditText inputPhoneEt;

    // 验证码输入框
    private EditText inputCodeEt;

    // 获取验证码按钮
    private Button requestCodeBtn;

    // 验证按钮
    private Button commitBtn;

    //倒计时
    int i = 30;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_phone);
        init();        //初始化控件
    }

    private void init() {
        inputPhoneEt = (EditText) findViewById(R.id.phone);
        inputCodeEt = (EditText) findViewById(R.id.et_yanzheng);
        requestCodeBtn = (Button) findViewById(R.id.but_yanzheng);
        commitBtn = (Button) findViewById(R.id.check);
        requestCodeBtn.setOnClickListener(this);
        commitBtn.setOnClickListener(this);

        // 启动短信验证sdk
        MobSDK.init(this, APPKEY, APPSECRETE);
        EventHandler eventHandler = 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;
                handler.sendMessage(msg);
            }
        };
        //注册回调监听接口
        SMSSDK.registerEventHandler(eventHandler);
    }

    @Override
    public void onClick(View v) {
        String phone = inputPhoneEt.getText().toString();
        switch (v.getId()) {
            case R.id.phone:
                // 1. 通过规则判断手机号
                if (!judgePhoneNums(phone)) {
                    return;
                } // 2. 通过sdk发送短信验证
                SMSSDK.getVerificationCode("86", phone);

                // 3. 把按钮变成不可点击,并且显示倒计时(正在获取)
                requestCodeBtn.setClickable(false);
                requestCodeBtn.setText("重新发送(" + i + ")");
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (; i > 0; i--) {
                            handler.sendEmptyMessage(-9);
                            if (i <= 0) { break; } try thread.sleep(1000); catch (interruptedexception e) e.printstacktrace(); handler.sendemptymessage(-8); }).start(); case r.id.check: 将收到的验证码和手机号提交再次核对 smssdk.submitverificationcode("86", phone, inputcodeet .gettext().tostring()); createprogressbar(); handler handler() public void handlemessage(message msg) if (msg.what="=" -9) requestcodebtn.settext("重新发送(" + i ")"); else -8) requestcodebtn.settext("获取验证码"); requestcodebtn.setclickable(true); int event="msg.arg1;" result="msg.arg2;" object data="msg.obj;" log.e("event", "event=" + event);
                if (result == SMSSDK.RESULT_COMPLETE) {
                    // &#x77ED;&#x4FE1;&#x6CE8;&#x518C;&#x6210;&#x529F;&#x540E;&#xFF0C;&#x8FD4;&#x56DE;MainActivity,&#x7136;&#x540E;&#x63D0;&#x793A;
                    if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {// &#x63D0;&#x4EA4;&#x9A8C;&#x8BC1;&#x7801;&#x6210;&#x529F;
                        Toast.makeText(getApplicationContext(), " 提交验证码成功", toast.length_short).show(); intent intent(phoneactivity.this, loginactivity.class); startactivity(intent); (event="=" smssdk.event_get_verification_code) toast.maketext(getapplicationcontext(), "正在获取验证码", ((throwable) data).printstacktrace(); }; private boolean judgephonenums(string phonenums) (ismatchlength(phonenums, 11) && ismobileno(phonenums)) return true; toast.maketext(this, "手机号码输入有误!", false; static ismatchlength(string str, length) (str.isempty()) str.length()="=" length ? true : ismobileno(string mobilenums) * 移动:134、135、136、137、138、139、150、151、157(td)、158、159、187、188 联通:130、131、132、152、155、156、185、186 电信:133、153、180、189、(1349卫通) 总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9 string telregex="[1][356]\\d{9}" ; "[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。 (textutils.isempty(mobilenums)) mobilenums.matches(telregex); createprogressbar() framelayout layout="(FrameLayout)" findviewbyid(android.r.id.content); framelayout.layoutparams layoutparams="new" framelayout.layoutparams( framelayout.layoutparams.wrap_content, framelayout.layoutparams.wrap_content); layoutparams.gravity="Gravity.CENTER;" progressbar mprobar="new" progressbar(this); mprobar.setlayoutparams(layoutparams); mprobar.setvisibility(view.visible); layout.addview(mprobar); @override protected ondestroy() smssdk.unregisteralleventhandler(); super.ondestroy(); }< code></=>

上面这串代码为啥作用不起来,奇怪了呢
* 验证码功能代码段2:显示有网络问题

package com.example.myapplication.widget;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.myapplication.R;
import com.example.myapplication.Shixian.Utils;

import org.json.JSONException;
import org.json.JSONObject;

import cn.smssdk.EventHandler;
import cn.smssdk.SMSSDK;

public class PhoneActivity extends AppCompatActivity {

    private Button buttonCode,buttonLogin;
    private EditText editTextPhoneNum,editTextCode;
    private String phoneNum,code;
    private EventHandler eh;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_phone);
        buttonCode = findViewById(R.id.but_yanzheng);
        buttonLogin = findViewById(R.id.check);
        editTextCode = findViewById(R.id.et_yanzheng);
        editTextPhoneNum = findViewById(R.id.phone);

        eh = new EventHandler() {
            @Override
            public void afterEvent(int event, int result, Object data) {
                if (result == SMSSDK.RESULT_COMPLETE){
                    //&#x56DE;&#x8C03;&#x5B8C;&#x6210;
                    if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
                        //&#x63D0;&#x4EA4;&#x9A8C;&#x8BC1;&#x7801;&#x6210;&#x529F;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(PhoneActivity.this,"&#x767B;&#x5F55;&#x6210;&#x529F;",Toast.LENGTH_SHORT).show();
                                //&#x5982;&#x679C;&#x9700;&#x8981;&#x8DF3;&#x8F6C;&#x53EF;&#x5728;&#x8FD9;&#x91CC;&#x8FDB;&#x884C;&#x8DF3;&#x8F6C;&#x9875;&#x9762;
                                //&#x767B;&#x5F55;&#x6210;&#x529F;&#x8DF3;&#x8F6C;&#x5230;&#x8F6F;&#x4EF6;&#x9996;&#x9875;&#x9875;&#x9762;
                                Intent intent=new Intent(PhoneActivity.this,RegisterActivity.class);
                                startActivity(intent);
                            }
                        });
                    }else if (event == SMSSDK.EVENT_GET_VOICE_VERIFICATION_CODE){
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(PhoneActivity.this,"&#x8BED;&#x97F3;&#x9A8C;&#x8BC1;&#x53D1;&#x9001;",Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                    else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE){
                        //&#x83B7;&#x53D6;&#x9A8C;&#x8BC1;&#x7801;&#x6210;&#x529F;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(PhoneActivity.this,"&#x9A8C;&#x8BC1;&#x7801;&#x5DF2;&#x53D1;&#x9001;",Toast.LENGTH_SHORT).show();
                            }
                        });
                    }else if (event == SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES){
                        Log.i("test","test");
                    }
                }else{
                    ((Throwable)data).printStackTrace();
                    Throwable throwable = (Throwable) data;
                    throwable.printStackTrace();
                    Log.i("1234",throwable.toString());
                    try {
                        JSONObject obj = new JSONObject(throwable.getMessage());
                        final String des = obj.optString("detail");
                        if (!TextUtils.isEmpty(des)){
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(PhoneActivity.this,des,Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        //&#x6CE8;&#x518C;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x56DE;&#x8C03;&#x76D1;&#x542C;&#xFF0C;&#x7528;&#x4E8E;&#x5904;&#x7406;SMSSDK&#x63A5;&#x53E3;&#x8BF7;&#x6C42;&#x7684;&#x7ED3;&#x679C;
        SMSSDK.registerEventHandler(eh);
        buttonCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                phoneNum = editTextPhoneNum.getText().toString();
                if(!phoneNum.isEmpty()){
                    if(Utils.checkTel(phoneNum)){ //&#x5229;&#x7528;&#x6B63;&#x5219;&#x8868;&#x8FBE;&#x5F0F;&#x83B7;&#x53D6;&#x68C0;&#x9A8C;&#x624B;&#x673A;&#x53F7;
                        // &#x83B7;&#x53D6;&#x9A8C;&#x8BC1;&#x7801;
                        SMSSDK.getVerificationCode("86", phoneNum);
                    }else{
                        Toast.makeText(getApplicationContext(),"&#x8BF7;&#x8F93;&#x5165;&#x6709;&#x6548;&#x7684;&#x624B;&#x673A;&#x53F7;",Toast.LENGTH_LONG).show();
                    }
                }else {
                    Toast.makeText(getApplicationContext(),"&#x8BF7;&#x8F93;&#x5165;&#x624B;&#x673A;&#x53F7;",Toast.LENGTH_LONG).show();
                    return;
                }
                phoneNum = editTextPhoneNum.getText().toString();
            }
        });
        buttonLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                code = editTextCode.getText().toString();
                if(!code.isEmpty()){
                    //&#x63D0;&#x4EA4;&#x9A8C;&#x8BC1;&#x7801;
                    SMSSDK.submitVerificationCode("86", phoneNum, code);
                }else{
                    Toast.makeText(getApplicationContext(),"&#x8BF7;&#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;",Toast.LENGTH_LONG).show();
                    return;
                }
            }
        });
    }
    // &#x4F7F;&#x7528;&#x5B8C;EventHandler&#x9700;&#x6CE8;&#x9500;&#xFF0C;&#x5426;&#x5219;&#x53EF;&#x80FD;&#x51FA;&#x73B0;&#x5185;&#x5B58;&#x6CC4;&#x6F0F;
    @Override
    protected void onDestroy() {
        super.onDestroy();
        SMSSDK.unregisterEventHandler(eh);
    }
}
package com.example.myapplication.Shixian;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ClassName:Utils
 * Package:com.example.myapplication.Shixian
 * Description: meet 985&ta
 *
 * @Data:2021/11/11 9:54
 * @Author:&#x707F;&#x707F;&#x7761;&#x9192;&#x4E86;
 */
public class Utils {
    /**
     * &#x6B63;&#x5219;&#x5339;&#x914D;&#x624B;&#x673A;&#x53F7;&#x7801;:
     */
    public static boolean checkTel(String tel) {
        Pattern p = Pattern.compile("^[1][3,4,5,6,7,8,9][0-9]{9}$");
        Matcher matcher = p.matcher(tel);
        return matcher.matches();
    }
}

不知道为啥。。。
* 使用步骤:
* 概述 SharedPreferences是一种轻量级的数据存储方式,采用键值对的存储方式。 SharedPreferences 只能存储少量数据,大量数据不能使用该方式存储,支持存储的数据类型有 booleans, floats, ints, longs, and strings。 SharedPreferences 存储到一个XML文件中的/data/data/
* 基本用法
1.获取SharedPreferences对象

`
mContextSp = this.getSharedPreferences( “testContextSp”, Context.MODE_PRIVATE );
mActivitySp = this.getPreferences( Context.MODE_PRIVATE );

Original: https://blog.csdn.net/qq_45870024/article/details/121212143
Author: cc睡醒了
Title: Android版QQ的实现

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/815892/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球