我在 android 中的 DatabaseHandler.kt 类中实现了一个 Toast 方法,但出现了错误,即无法使用提供的参数(即 Toast.makeTest() 函数)调用任何函数。 代码如下:
package com.example.pama.pamaDB
import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.os.Build
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.content.ContentProviderCompat.requireContext
import org.mindrot.jbcrypt.BCrypt
import java.util.regex.Pattern
const val dbname = "UserDb"
const val tbname = "Users"
const val col_username = "username"
const val col_email = "email"
const val col_passwordHash = "passwordHash" // Store hashed password instead of plain text
const val col_id = "id"
class DatabaseHandler(context: Context) : SQLiteOpenHelper(context, dbname, null, 1) {
override fun onCreate(db: SQLiteDatabase?) {
val createTable = "CREATE TABLE " + tbname + "(" +
col_id + " INTEGER PRIMARY KEY AUTOINCREMENT," +
col_username + " VARCHAR(256) UNIQUE," + // Enforce unique usernames
col_email + " VARCHAR(256) UNIQUE," + // Enforce unique emails
col_passwordHash + " VARCHAR(256) NOT NULL" + // Store hashed password securely
")"
db?.execSQL(createTable)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
// TODO: Implement migration logic if needed
}
// Securely inserts a new user with password hashing
@RequiresApi(Build.VERSION_CODES.O)
fun insertData(user: Users) {
val db = writableDatabase
val cv = ContentValues()
val context = this
// Validate email format:
if (!isValidEmail(user.email)) {
val context = this
val text: CharSequence = "Invalid Email Format"
val duration: Int = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
}
// Enforce unique username and email:
if (isUsernameUnique(user.username) && isEmailUnique(user.email)) {
// Hash password securely using BCrypt algorithm
val workFactor = 12
user.passwordHash = BCrypt.hashpw(user.password, BCrypt.gensalt(workFactor)) // Implement secure hashing
cv.put(col_username, user.username)
cv.put(col_email, user.email)
cv.put(col_passwordHash, user.passwordHash as String)
val result = db.insert(tbname, null, cv)
if (result == -1L) {
Toast.makeText(context, "Failed", Toast.LENGTH_LONG).show()
} else {
Toast.makeText(context, "Success", Toast.LENGTH_LONG).show()
}
} else {
Toast.makeText(context, "Username or email already exists", Toast.LENGTH_SHORT).show()
}
}
private fun requireContext() {
val context: Context
return
}
private fun isEmailUnique(email: String): Boolean {
val db = writableDatabase
val query = "SELECT COUNT(*) FROM $tbname WHERE $col_email = ?"
val cursor = db.rawQuery(query, arrayOf(email))
return if (cursor.moveToFirst()) {
val count = cursor.getInt(0)
cursor.close()
count == 0 // Username is unique if count is 0
} else {
cursor.close()
false // Error checking: assume non-unique if query fails
}
}
private fun isUsernameUnique(username: String): Boolean {
val db = writableDatabase
val query = "SELECT COUNT(*) FROM $tbname WHERE $col_username = ?"
val cursor = db.rawQuery(query, arrayOf(username))
return if (cursor.moveToFirst()) {
val count = cursor.getInt(0)
cursor.close()
count == 0 // Username is unique if count is 0
} else {
cursor.close()
false // Error checking: assume non-unique if query fails
}
}
// Securely finds a user by username with password comparison
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("Range")
fun findUserByUsername(username: String): Users? {
val db = writableDatabase
val query = "SELECT * FROM $tbname WHERE $col_username = ?"
val cursor = db.rawQuery(query, arrayOf(username))
if (cursor.moveToFirst()) {
val user = Users(
cursor.getInt(cursor.getColumnIndex(col_id)),
cursor.getString(cursor.getColumnIndex(col_username)),
cursor.getString(cursor.getColumnIndex(col_email)),
null
)
// Securely compare entered password with stored hash using BCrypt:
return if (BCrypt.checkpw(col_passwordHash, user.passwordHash.toString())) {
cursor.close()
return user
} else {
// Invalid password
cursor.close()
null
}
} else {
cursor.close()
return null
}
}
// Optimized email validation with Pattern:
@SuppressLint("Range")
private fun isValidEmail(email: String): Boolean {
val emailRegex = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
// Optimize using Pattern for repeated validation:
val pattern = Pattern.compile(emailRegex)
return pattern.matcher(email).matches()
}
}
我尝试直接使用此关键字代替上下文作为变量,但没有任何改变。请提供任何帮助。
val context=this
导致上下文不是Context
,但它将是DatabaseHandler
对象的实例;这就是问题所在。
DatabaseHandler
类的实例。您需要一种将 Context 传递给使用 Context 的函数的方法,或者一种检索适当 Context 的方法,这可能更难以正确检索。
也许是这样的:-
fun insertData(user: Users, context: Context) {
....
}
val context=this
简单演示
使用 DatabaseHandler 的精简版本,如下所示:-
class DatabaseHandler(context: Context) : SQLiteOpenHelper(context, dbname, null, 1) {
override fun onCreate(db: SQLiteDatabase?) {
val createTable = "CREATE TABLE " + tbname + "(" +
col_id + " INTEGER PRIMARY KEY AUTOINCREMENT," +
col_username + " VARCHAR(256) UNIQUE," + // Enforce unique usernames
col_email + " VARCHAR(256) UNIQUE," + // Enforce unique emails
col_passwordHash + " VARCHAR(256) NOT NULL" + // Store hashed password securely
")"
db?.execSQL(createTable)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
// TODO: Implement migration logic if needed
}
// Securely inserts a new user with password hashing
@RequiresApi(Build.VERSION_CODES.O)
fun insertData(user: Users, context: Context) {
val db = writableDatabase
val cv = ContentValues()
// Validate email format:
//if (!isValidEmail(user.email)) {
//val context = this
val text: CharSequence = "Invalid Email Format"
val duration: Int = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
//}
}
}
还有活动代码(可以转换为上下文):-
class MainActivity : AppCompatActivity() {
lateinit var databaseHandler: DatabaseHandler
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
databaseHandler = DatabaseHandler(this)
databaseHandler.insertData(Users(100,"Fred","[email protected]","blah"),this)
databaseHandler.insertData(Users(200,"Mary","[email protected]","blah"),this)
databaseHandler.insertData(Users(300,"Jane","[email protected]","blah"),this)
}
}
insertData
函数的使用运行时:-