📜  Kotlin Android Web服务

📅  最后修改于: 2021-01-05 08:53:59             🧑  作者: Mango

Kotlin Android Web服务-Volley库注册,登录和注销教程

在本教程中,我们将使用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_main.xml




    

        

        


            

                

                

            

            

                

                

            

            

                

                

            

            

                

                

            


        

        

现在,使用以下代码在布局目录中创建一个activity_login.xml文件。此活动用于用户登录UI。

activity_login.xml




    

    

    

    

使用以下代码在布局目录中创建一个activity_register.xml文件。此活动用于用户注册UI。

activity_register.xml





    

        

        

        

        

        

            


            

        

        

在build.gradle文件中添加volley库依赖项。

build.gradle

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的数据模型类。

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。

URLs.kt

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"
}

VolleySingleton.kt

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类包含具有以下功能的四个方法:

  • userLogin():此函数用于在登录后将用户信息存储在SharedPreferences中。
  • isLoggedIn:此方法检查用户是否已经登录。
  • user:User get():如果登录,此方法获取用户信息。
  • logout():此函数清除SharedPreferences数据并注销用户。

SharedPrefManager.kt

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()方法注销用户。

MainActivity.kt

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和响应的参数。

LoginActivity.kt

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处理服务器生成的响应。

RegisterActivity.kt

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

在AndroidManifest.xml文件中添加以下权限



注意:服务器端的注册和登录代码是通过MySQL和MySQL在https://www.javatpoint.com/android-volley-library-registration-login-logout上实现的。

输出: