Untitled
unknown
plain_text
a month ago
17 kB
3
Indexable
package com.example.safety.activity import android.app.Activity import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import android.os.Bundle import android.os.Handler import android.os.Looper import android.os.VibrationEffect import android.os.Vibrator import android.provider.ContactsContract import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.KeyEvent import android.view.View import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager import android.widget.Toast import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.example.safety.R import com.example.safety.api.RetrofitInstance import com.example.safety.common.Constants import com.example.safety.common.SharedPrefFile import com.example.safety.databinding.ActivityRegisterUserBinding import com.example.safety.models.NewRegistrationResponse import com.example.safety.models.UserModelItem import com.google.firebase.firestore.FirebaseFirestore import com.google.gson.Gson import org.json.JSONObject import retrofit2.Call import retrofit2.Callback import retrofit2.Response /** * RegisterUserActivity * * This activity allows new users to sign up for an account. * It collects user details and stores them in the database. */ class RegisterUserActivity : AppCompatActivity() { private val TAG = "Register User" // Tag for logging purposes private lateinit var binding: ActivityRegisterUserBinding // View binding for UI elements private lateinit var pickContactLauncher: ActivityResultLauncher<Intent> // Launcher for picking contacts var phoneNum = "" // Stores the selected contact's phone number var name = "" // Stores the selected contact's name override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val fdb = FirebaseFirestore.getInstance() // Firestore database instance val retrofit = RetrofitInstance.initialize() // Retrofit instance for API calls val sharedpref = SharedPrefFile // Shared preferences instance sharedpref.init(this) // Initialize shared preferences binding = ActivityRegisterUserBinding.inflate(layoutInflater) setContentView(binding.root) // Set the content view using binding val editTexts = listOf(binding.pin1, binding.pin2, binding.pin3, binding.pin4, binding.pin5) for (i in editTexts.indices) { editTexts[i].addTextChangedListener(object : TextWatcher { private var lastText = "" override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { lastText = s.toString() // Store previous text } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { if (s.toString() != lastText) { // Only act if text actually changed if (s?.length == 1 && i < editTexts.size - 1) { editTexts[i + 1].requestFocus() // Move forward when typing } else if (s.isNullOrEmpty() && i > 0) { editTexts[i - 1].requestFocus() // Move back when deleting editTexts[i - 1].setText("") // Also clear previous box } } } }) // Prevent focus jumping unexpectedly editTexts[i].setOnFocusChangeListener { _, hasFocus -> if (hasFocus && editTexts[0].text.isEmpty()) { editTexts[0].requestFocus() } } } binding.phoneNumber.apply { setText("+91 ") // Set default prefix setSelection(text?.length ?: 0) // Move cursor to the end addTextChangedListener(object : TextWatcher { private var isEditing = false // Flag to prevent infinite loops override fun beforeTextChanged( s: CharSequence?, start: Int, count: Int, after: Int, ) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { if (isEditing || s == null) return isEditing = true // Ensure "+91 " prefix is always there if (!s.startsWith("+91 ")) { setText("+91 ") } // Prevent cursor from moving inside "+91 " if (selectionStart < 4) { setSelection(text?.length ?: 0) } // Extract actual phone number (excluding "+91 ") val phoneNumber = s.toString().replace("+91 ", "") // Show error if phone number is not exactly 10 digits binding.phoneNumberLayout.error = if (phoneNumber.length != 10) { "Phone number should be 10 digits" } else { null // Remove error when valid } isEditing = false } }) } // Redirects user to login activity if already registered binding.tVAlreadyReg.setOnClickListener { val intent = Intent(this, LoginUserActivity::class.java) startActivity(intent) finish() } // Initializes the contact picker launcher pickContactLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { val data: Intent? = result.data handleContactResult(data) // Handle contact selection } } binding.apply { nextToNumberLL.setOnClickListener { nepLL.visibility = View.GONE numberLL.visibility = View.VISIBLE pinLL.visibility = View.GONE } nextToPinLL.setOnClickListener { nepLL.visibility = View.GONE numberLL.visibility = View.GONE pinLL.visibility = View.VISIBLE } backToNepLL.setOnClickListener { nepLL.visibility = View.VISIBLE numberLL.visibility = View.GONE pinLL.visibility = View.GONE } backToNumberLL.setOnClickListener { nepLL.visibility = View.GONE numberLL.visibility = View.VISIBLE pinLL.visibility = View.GONE } } // Opens the contact picker when selecting a trusted contact binding.trustedContactNumber.setOnClickListener { pickContact() } // Handles user registration process when "Register" button is clicked binding.RegisterBtn.setOnClickListener { val fullname = binding.tilName.editText?.text.toString() val phoneNumber = binding.phoneNumber.text.toString() val organization = binding.tilOrganization.editText?.text.toString() val email = binding.tilemail.editText?.text.toString() val password = binding.tilpassword.editText?.text.toString() val securityPIN = editTexts.joinToString("") { it.text.toString() } // val securityPIN = binding.tilSecurityPIN.editText?.text.toString() // Ensures all fields are filled before proceeding if (email.isBlank() || password.isBlank() || organization.isBlank() || fullname.isBlank() || phoneNumber.isBlank() || phoneNum.isBlank() || name.isBlank() || securityPIN.isBlank()) { Toast.makeText(this, "Enter all the details", Toast.LENGTH_SHORT).show() } else if (phoneNumber.length != 14) { Toast.makeText(this, "Phone Number should be of 10 digits", Toast.LENGTH_SHORT) .show() } else if (securityPIN.length != 5) { Toast.makeText(this, "Security PIN should be of 5 digits", Toast.LENGTH_SHORT) .show() } else { binding.progressBar.visibility = View.VISIBLE binding.mainContent.visibility = View.GONE // Creating a new user object val newUser = UserModelItem( organization = organization, email = email, password = password, fullName = fullname, userID = (100..1000).random().toString(), organizationID = (100..1000).random().toString(), phoneNumber = phoneNumber, trustedContactID = (100..1000).random().toString(), trustedContactNumber = Constants.normalizePhoneNumber(phoneNum).toString(), trustedContactName = name, securityPIN = securityPIN ) Log.d("RegisterUser", "$newUser") val jsonBody = Gson().toJson(newUser) Log.d("${Constants.TAG} API_REQUEST", "JSON Body: $jsonBody") // Sending the user data to the backend API for registration retrofit.registerNewUser(newUser) .enqueue(object : Callback<NewRegistrationResponse> { override fun onResponse( call: Call<NewRegistrationResponse>, response: Response<NewRegistrationResponse>, ) { Log.d("${Constants.TAG} RegisterUser", "Response: ${response.body()}") try { if (response.isSuccessful) { // Successfully registered sharedpref.putLoggedInfo(Constants.SP_LOGGED_INFO, true) sharedpref.putUserData(Constants.SP_USERDATA, newUser) Log.d("${Constants.TAG} RegisterUser", "New User: ${newUser}") val fdbData = hashMapOf( "lat" to "0.0", "long" to "0.0", "connectionInfo" to "null", "batPer" to 0, "name" to "name", "phoneNumber" to "1111111" ) // Save user location info in Firestore fdb.collection(Constants.FIRESTORE_COLLECTION).document(email) .set(fdbData) .addOnSuccessListener { Log.d("RegisterUser", "New Firebase entry: $fdbData") } .addOnFailureListener { Log.d( "RegisterUser", "Error in Firebase: ${it.message}" ) } binding.progressBar.visibility = View.GONE binding.mainContent.visibility = View.VISIBLE startActivity(Intent(baseContext, MainActivity::class.java)) finish() } else { // Handles 400, 404, 500 val errorMessage = JSONObject( response.errorBody()?.string().toString() ).getString("message") ?: "Unknown error" Toast.makeText(baseContext, errorMessage, Toast.LENGTH_SHORT) .show() } } catch (e: Exception) { Log.e( "${Constants.TAG} ProfileFragment", "Error processing response: ${e.message}" ) Toast.makeText( baseContext, "Something went wrong!", Toast.LENGTH_SHORT ).show() } } override fun onFailure(call: Call<NewRegistrationResponse>, t: Throwable) { Log.d("RegisterUser", "API Call Failed: ${t.message}") } }) } } } private val READ_CONTACTS_PERMISSION_REQUEST = 1 // Permission request code for reading contacts /** * Initiates contact picking by checking permissions */ private fun pickContact() { if (ContextCompat.checkSelfPermission( this, android.Manifest.permission.READ_CONTACTS ) != PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions( this, arrayOf(android.Manifest.permission.READ_CONTACTS), READ_CONTACTS_PERMISSION_REQUEST ) } else { launchContactPicker() } } /** * Handles permission request results for reading contacts */ override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray, ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == READ_CONTACTS_PERMISSION_REQUEST) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { launchContactPicker() } else { Toast.makeText( this, "Permission denied. Cannot access contacts.", Toast.LENGTH_SHORT ).show() } } } /** * Launches the contact picker */ private fun launchContactPicker() { val intent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI) pickContactLauncher.launch(intent) } /** * Handles the result of the contact picker */ private fun handleContactResult(data: Intent?) { if (data != null) { val contactUri: Uri = data.data!! val cursor = contentResolver.query(contactUri, null, null, null, null) cursor?.use { if (it.moveToFirst()) { val id = it.getString(it.getColumnIndexOrThrow(ContactsContract.Contacts._ID)) name = it.getString(it.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)) val hasPhone = it.getInt(it.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER)) if (hasPhone > 0) { val phoneCursor = contentResolver.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", arrayOf(id), null ) phoneCursor?.use { phone -> if (phone.moveToFirst()) { phoneNum = phone.getString(phone.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER)) binding.trustedContactNumber.setText("$name - $phoneNum") } } } else { Toast.makeText(this, "Contact has no phone number", Toast.LENGTH_SHORT) .show() } } } } } }
Editor is loading...
Leave a Comment