Android - 错误提示:无法使用提供的参数调用以下函数:DataBaseHelper 类中的 Toast.maketest() 函数

问题描述 投票:0回答:1

我在 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()
    }
}

我尝试直接使用此关键字代替上下文作为变量,但没有任何改变。请提供任何帮助。

android sqlite kotlin android-sqlite
1个回答
0
投票

val context=this
导致上下文不是
Context
,但它将是
DatabaseHandler
对象
的实例;这就是问题所在。

  • this用于引用类的当前实例,该类是
    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)
    }
}
  • 注意 DatabaseHandler 实例的
    insertData
    函数的使用

运行时:-

  • Toast 出现
© www.soinside.com 2019 - 2024. All rights reserved.