Android Studio中SQLite+Kotlin登录注册验证失败问题求助
登录验证失败问题修复方案
问题根源分析
以下代码中的几个错误导致登录时提示“无效的用户名和密码”:
- 注册参数顺序颠倒:
RegisterActivity调用db.register时,密码和邮箱参数传递顺序错误,导致数据库中密码字段存储的是邮箱值,登录时无法匹配。 - 登录控件ID错误:
LoginActivity使用了注册页面的控件ID获取输入,实际读取的不是登录页面的用户名和密码内容。 - 游标管理不规范:数据库查询游标未使用安全的资源管理方式,存在内存泄漏风险。
修复后的代码实现
1. 修正RegisterActivity参数传递
package com.example.app import android.content.Intent import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity class RegisterActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_register) val regUserName = findViewById<EditText>(R.id.regUuserNameSection) val regEmail = findViewById<EditText>(R.id.regemailSection) val regPassword = findViewById<EditText>(R.id.regpasswordSection) val confirm = findViewById<EditText>(R.id.regConformPasswordSection) val regButton = findViewById<Button>(R.id.regButton) val loginText = findViewById<TextView>(R.id.registration) loginText.setOnClickListener { startActivity(Intent(this, LoginActivity::class.java)) } regButton.setOnClickListener { val username = regUserName.text.toString().trim() val email = regEmail.text.toString().trim() val password = regPassword.text.toString().trim() val conform = confirm.text.toString().trim() val db = Data(applicationContext, "healthcare", null, 1) if (username.isEmpty() || email.isEmpty() || password.isEmpty() || conform.isEmpty()) { Toast.makeText(this, "请填写所有信息", Toast.LENGTH_SHORT).show() } else { if (password == conform) { if (isValid(password)) { db.register(username, password, email) // 修正参数顺序 Toast.makeText(this, "注册成功", Toast.LENGTH_SHORT).show() startActivity(Intent(this, LoginActivity::class.java)) } else { Toast.makeText(this, "密码需包含至少8个字符、一个大写字母、一个数字和一个特殊符号", Toast.LENGTH_LONG).show() } } else { Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show() } } } } private fun isValid(password: String): Boolean { val passwordRegex = Regex("^(?=.*[A-Z])(?=.*[!@#\$&*])(?=.*[0-9])(?=.{9,17}).*$") return password.matches(passwordRegex) } }
2. 修正LoginActivity控件ID
(注意:请根据实际登录布局文件调整控件ID)
package com.example.app import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity class LoginActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) // 使用登录页面正确的控件ID val edUserName: EditText = findViewById(R.id.loginUsername) val edPassword: EditText = findViewById(R.id.loginPassword) val loginButton: Button = findViewById(R.id.loginButton) val newRegister: TextView = findViewById(R.id.toRegister) val db = Data(applicationContext, "healthcare", null, 1) loginButton.setOnClickListener { val username = edUserName.text.toString().trim() val password = edPassword.text.toString().trim() if (username.isEmpty() || password.isEmpty()) { Toast.makeText(this, "请填写用户名和密码", Toast.LENGTH_SHORT).show() } else { if (db.login(username, password) == 1) { Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show() val sharedPref = getSharedPreferences("share_prefs", Context.MODE_PRIVATE) sharedPref.edit().putString("username", username).apply() startActivity(Intent(this, HomeActivity::class.java)) } else { Toast.makeText(this, "无效的用户名或密码", Toast.LENGTH_SHORT).show() } } } newRegister.setOnClickListener { startActivity(Intent(this, RegisterActivity::class.java)) } } }
3. 修正Data类的数据库操作
package com.example.app import android.content.ContentValues import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper class Data( context: Context?, name: String?, factory: SQLiteDatabase.CursorFactory?, version: Int ) : SQLiteOpenHelper(context, name, factory, version) { override fun onCreate(db: SQLiteDatabase) { val query = "CREATE TABLE $TABLE_NAME ($USERNAME_COL TEXT, $PASSWORD_COL TEXT, $EMAIL_COL TEXT)" db.execSQL(query) } override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { db?.execSQL("DROP TABLE IF EXISTS $TABLE_NAME") onCreate(db!!) } fun register(username: String, password: String, email: String) { val cv = ContentValues().apply { put(USERNAME_COL, username) put(PASSWORD_COL, password) put(EMAIL_COL, email) } writableDatabase.use { db -> db.insert(TABLE_NAME, null, cv) } } fun login(username: String, password: String): Int { var result = 0 val selectionArgs = arrayOf(username, password) readableDatabase.use { db -> db.rawQuery("SELECT * FROM $TABLE_NAME WHERE $USERNAME_COL =? AND $PASSWORD_COL =?", selectionArgs).use { cursor -> if (cursor.moveToFirst()) { result = 1 } } } return result } companion object { const val TABLE_NAME = "users" const val USERNAME_COL = "username" const val PASSWORD_COL = "password" const val EMAIL_COL = "email" } }
额外注意事项
- 确保登录布局文件的控件ID与
LoginActivity中使用的ID完全一致 - 生产环境中建议对密码进行加密存储(如SHA-256)
- 可添加用户名唯一性校验,避免重复注册
内容的提问来源于stack exchange,提问作者Venkata Kishore
相关产品推荐
相关产品推荐

