📅  最后修改于: 2021-01-05 08:53:59             🧑  作者: Mango
在本教程中,我们将使用Volley库和JSON创建基本的用户注册和登录模块。 Volley是一个HTTP库,它为我们的应用程序提供了网络连接功能。
使用MySQL与PHP创建注册和登录的Web API。在实施客户端Android应用程序代码之前,请先在https://www.javatpoint.com/android-volley-library-registration-login-logout查看服务器端API代码。
在Android应用程序中,我们将创建用于用户注册,用户登录的三个活动类,并在主要活动中(作为配置文件)显示用户详细信息。
在布局中创建一个activity_main.xml并添加以下代码。此活动用于显示用户配置文件的详细信息。
现在,使用以下代码在布局目录中创建一个activity_login.xml文件。此活动用于用户登录UI。
使用以下代码在布局目录中创建一个activity_register.xml文件。此活动用于用户注册UI。
在build.gradle文件中添加volley库依赖项。
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
implementation 'com.android.volley:volley:1.0.0'
}
使用以下代码创建一个名为User.kt的数据模型类。
package example.javatpoint.com.kotlinvolleyregistrationloginsystem
class User(var id: Int, var name: String?, var email: String?, var gender: String?)
我们需要定义调用服务器端API的URL。
创建一个URLs.kt类并定义URL。
package example.javatpoint.com.kotlinvolleyregistrationloginsystem
object URLs {
private val ROOT_URL = "http://192.168.1.35/androidphpmysql/registrationapi.php?apicall="
val URL_REGISTER = ROOT_URL + "signup"
val URL_LOGIN = ROOT_URL + "login"
}
package example.javatpoint.com.kotlinvolleyregistrationloginsystem
import android.content.Context
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.toolbox.Volley
class VolleySingleton private constructor(context: Context) {
private var mRequestQueue: RequestQueue
// applicationContext is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
val requestQueue: RequestQueue
get() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(mCtx?.applicationContext)
}
return mRequestQueue
}
init {
mCtx = context
mRequestQueue = requestQueue
}
fun addToRequestQueue(req: Request) {
requestQueue.add(req)
}
companion object {
private var mInstance: VolleySingleton? = null
private var mCtx: Context? = null
@Synchronized
fun getInstance(context: Context): VolleySingleton {
if (mInstance == null) {
mInstance = VolleySingleton(context)
}
return mInstance as VolleySingleton
}
}
}
创建一个名为SharedPreferences.kt的类。在此类中,我们使用SharedPreferences类存储用户详细信息。 SharedPreferences类包含具有以下功能的四个方法:
package example.javatpoint.com.kotlinvolleyregistrationloginsystem
import android.content.Context
import android.content.Intent
class SharedPrefManager private constructor(context: Context) {
//this method will checker whether user is already logged in or not
val isLoggedIn: Boolean
get() {
val sharedPreferences = ctx?.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE)
return sharedPreferences?.getString(KEY_USERNAME, null) != null
}
//this method will give the logged in user
val user: User
get() {
val sharedPreferences = ctx?.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE)
return User(
sharedPreferences!!.getInt(KEY_ID, -1),
sharedPreferences.getString(KEY_USERNAME, null),
sharedPreferences.getString(KEY_EMAIL, null),
sharedPreferences.getString(KEY_GENDER, null)
)
}
init {
ctx = context
}
//this method will store the user data in shared preferences
fun userLogin(user: User) {
val sharedPreferences = ctx?.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE)
val editor = sharedPreferences?.edit()
editor?.putInt(KEY_ID, user.id)
editor?.putString(KEY_USERNAME, user.name)
editor?.putString(KEY_EMAIL, user.email)
editor?.putString(KEY_GENDER, user.gender)
editor?.apply()
}
//this method will logout the user
fun logout() {
val sharedPreferences = ctx?.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE)
val editor = sharedPreferences?.edit()
editor?.clear()
editor?.apply()
ctx?.startActivity(Intent(ctx, LoginActivity::class.java))
}
companion object {
private val SHARED_PREF_NAME = "volleyregisterlogin"
private val KEY_USERNAME = "keyusername"
private val KEY_EMAIL = "keyemail"
private val KEY_GENDER = "keygender"
private val KEY_ID = "keyid"
private var mInstance: SharedPrefManager? = null
private var ctx: Context? = null
@Synchronized
fun getInstance(context: Context): SharedPrefManager {
if (mInstance == null) {
mInstance = SharedPrefManager(context)
}
return mInstance as SharedPrefManager
}
}
}
现在,在MainActivity.kt类中,如果用户已登录,我们将显示用户信息,否则,它将重定向到LoginActivity.kt类。当单击按钮时,使用onClick()方法注销用户。
package example.javatpoint.com.kotlinvolleyregistrationloginsystem
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.content.Intent
import android.view.View
import android.widget.Button
import android.widget.TextView
class MainActivity : AppCompatActivity(), View.OnClickListener {
internal lateinit var id: TextView
internal lateinit var userName: TextView
internal lateinit var userEmail: TextView
internal lateinit var gender: TextView
internal lateinit var btnLogout: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (SharedPrefManager.getInstance(this).isLoggedIn) {
id = findViewById(R.id.textViewId)
userName = findViewById(R.id.textViewUsername)
userEmail = findViewById(R.id.textViewEmail)
gender = findViewById(R.id.textViewGender)
btnLogout = findViewById(R.id.buttonLogout)
val user = SharedPrefManager.getInstance(this).user
id.text = user.id.toString()
userEmail.text = user.email
gender.text = user.gender
userName.text = user.name
btnLogout.setOnClickListener(this)
} else {
val intent = Intent(this@MainActivity, LoginActivity::class.java)
startActivity(intent)
finish()
}
}
override fun onClick(view: View) {
if (view == btnLogout) {
SharedPrefManager.getInstance(applicationContext).logout()
}
}
}
在LoginActivity.kt类中,我们检查用户是否已经登录,如果为true,则重定向到MainActivity.kt类,否则,允许用户登录。
网络模块使用Volley库的StringRequest类。 StringRequest类的对象采用类型请求方法,URL和响应的参数。
package example.javatpoint.com.kotlinvolleyregistrationloginsystem
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.content.Intent
import android.text.TextUtils
import android.view.View
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.Toast
import com.android.volley.AuthFailureError
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import kotlinx.android.synthetic.main.activity_login.*
import org.json.JSONException
import org.json.JSONObject
import java.util.HashMap
class LoginActivity : AppCompatActivity() {
internal lateinit var etName: EditText
internal lateinit var etPassword: EditText
internal lateinit var progressBar: ProgressBar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
if (SharedPrefManager.getInstance(this).isLoggedIn) {
finish()
startActivity(Intent(this, MainActivity::class.java))
}
progressBar = findViewById(R.id.progressBar)
etName = findViewById(R.id.etUserName)
etPassword = findViewById(R.id.etUserPassword)
//calling the method userLogin() for login the user
btnLogin.setOnClickListener(View.OnClickListener {
userLogin()
})
//if user presses on textview it call the activity RegisterActivity
tvRegister.setOnClickListener(View.OnClickListener {
finish()
startActivity(Intent(applicationContext, RegisterActivity::class.java))
})
}
private fun userLogin() {
//first getting the values
val username = etName.text.toString()
val password = etPassword.text.toString()
//validating inputs
if (TextUtils.isEmpty(username)) {
etName.error = "Please enter your username"
etName.requestFocus()
return
}
if (TextUtils.isEmpty(password)) {
etPassword.error = "Please enter your password"
etPassword.requestFocus()
return
}
//if everything is fine
val stringRequest = object : StringRequest(Request.Method.POST, URLs.URL_LOGIN,
Response.Listener { response ->
progressBar.visibility = View.GONE
try {
//converting response to json object
val obj = JSONObject(response)
//if no error in response
if (!obj.getBoolean("error")) {
Toast.makeText(applicationContext, obj.getString("message"), Toast.LENGTH_SHORT).show()
//getting the user from the response
val userJson = obj.getJSONObject("user")
//creating a new user object
val user = User(
userJson.getInt("id"),
userJson.getString("username"),
userJson.getString("email"),
userJson.getString("gender")
)
//storing the user in shared preferences
SharedPrefManager.getInstance(applicationContext).userLogin(user)
//starting the MainActivity
finish()
startActivity(Intent(applicationContext, MainActivity::class.java))
} else {
Toast.makeText(applicationContext, obj.getString("message"), Toast.LENGTH_SHORT).show()
}
} catch (e: JSONException) {
e.printStackTrace()
}
},
Response.ErrorListener { error -> Toast.makeText(applicationContext, error.message, Toast.LENGTH_SHORT).show() }) {
@Throws(AuthFailureError::class)
override fun getParams(): Map {
val params = HashMap()
params["username"] = username
params["password"] = password
return params
}
}
VolleySingleton.getInstance(this).addToRequestQueue(stringRequest)
}
}
RegisterActivity.kt类用于注册用户。此类最初检查用户登录,如果为true,则重定向到MainActivity.kt类,否则,允许用户注册。
与LoginActivity.kt类类似,我们使用Volley库的StringRequest类进行网络连接,并传递类型请求方法,URL和响应的参数。 Response.Listener处理服务器生成的响应。
package example.javatpoint.com.kotlinvolleyregistrationloginsystem
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.content.Intent
import android.text.TextUtils
import android.view.View
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.Toast
import com.android.volley.AuthFailureError
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import kotlinx.android.synthetic.main.activity_register.*
import org.json.JSONException
import org.json.JSONObject
import java.util.HashMap
class RegisterActivity : AppCompatActivity() {
internal lateinit var editTextUsername: EditText
internal lateinit var editTextEmail: EditText
internal lateinit var editTextPassword: EditText
internal lateinit var radioGroupGender: RadioGroup
internal lateinit var progressBar: ProgressBar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
progressBar = findViewById(R.id.progressBar)
//if the user is already logged in we will directly start the MainActivity (profile) activity
if (SharedPrefManager.getInstance(this).isLoggedIn) {
finish()
startActivity(Intent(this, MainActivity::class.java))
return
}
editTextUsername = findViewById(R.id.editTextUsername)
editTextEmail = findViewById(R.id.editTextEmail)
editTextPassword = findViewById(R.id.editTextPassword)
radioGroupGender = findViewById(R.id.radioGender)
buttonRegister.setOnClickListener(View.OnClickListener {
//if user pressed on button register
//here we will register the user to server
registerUser()
})
textViewLogin.setOnClickListener(View.OnClickListener {
finish()
startActivity(Intent(this@RegisterActivity, LoginActivity::class.java))
})
}
private fun registerUser() {
val username = editTextUsername.text.toString().trim { it <= ' ' }
val email = editTextEmail.text.toString().trim { it <= ' ' }
val password = editTextPassword.text.toString().trim { it <= ' ' }
val gender = (findViewById(radioGroupGender.checkedRadioButtonId) as RadioButton).text.toString()
//first we will do the validations
if (TextUtils.isEmpty(username)) {
editTextUsername.error = "Please enter username"
editTextUsername.requestFocus()
return
}
if (TextUtils.isEmpty(email)) {
editTextEmail.error = "Please enter your email"
editTextEmail.requestFocus()
return
}
if (!android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
editTextEmail.error = "Enter a valid email"
editTextEmail.requestFocus()
return
}
if (TextUtils.isEmpty(password)) {
editTextPassword.error = "Enter a password"
editTextPassword.requestFocus()
return
}
val stringRequest = object : StringRequest(Request.Method.POST, URLs.URL_REGISTER,
Response.Listener { response ->
progressBar.visibility = View.GONE
try {
//converting response to json object
val obj = JSONObject(response)
//if no error in response
if (!obj.getBoolean("error")) {
Toast.makeText(applicationContext, obj.getString("message"), Toast.LENGTH_SHORT).show()
//getting the user from the response
val userJson = obj.getJSONObject("user")
//creating a new user object
val user = User(
userJson.getInt("id"),
userJson.getString("username"),
userJson.getString("email"),
userJson.getString("gender")
)
//storing the user in shared preferences
SharedPrefManager.getInstance(applicationContext).userLogin(user)
//starting the MainActivity activity
finish()
startActivity(Intent(applicationContext, MainActivity::class.java))
} else {
Toast.makeText(applicationContext, obj.getString("message"), Toast.LENGTH_SHORT).show()
}
} catch (e: JSONException) {
e.printStackTrace()
}
},
Response.ErrorListener { error -> Toast.makeText(applicationContext, error.message, Toast.LENGTH_SHORT).show() }) {
@Throws(AuthFailureError::class)
override fun getParams(): Map {
val params = HashMap()
params["username"] = username
params["email"] = email
params["password"] = password
params["gender"] = gender
return params
}
}
VolleySingleton.getInstance(this).addToRequestQueue(stringRequest)
}
}
在AndroidManifest.xml文件中添加以下权限
注意:服务器端的注册和登录代码是通过MySQL和MySQL在https://www.javatpoint.com/android-volley-library-registration-login-logout上实现的。
输出: