Я хочу определить 4-значный SMS-код от службы и автоматически заполнить созданные мной поля otp. Для этого я использовал документацию Google, источник:
https://developers.google.com/identity/ ... er/request
Я пишу с помощью Jetpack Compose, поэтому мне немного трудно его адаптировать. У меня более одного экрана, но вкратце операция выглядит следующим образом: доходит до экрана, где вводятся данные пользователя и номер телефона, после ввода информации я нажимаю кнопку продолжения, и когда я нажимаю кнопку, я отправляю данные пользователя и номер телефона в сервис, на номер телефона пользователя от сервиса отправляется смс. Конечно, когда он нажимает кнопку продолжения, он переходит на другой экран. На экране проверки есть 4 поля, я хочу, чтобы эти поля заполнялись автоматически, когда на телефон пользователя приходит смс. Я следовал по пути, указанному в документации Google, я пытался делать то, что написано в Интернете, но не смог найти результата, потому что некоторые не делали этого с помощью Compose, а некоторые не делились рабочим кодом, а некоторые устарели. .
Я кратко объяснил, что хочу сделать, на самом деле это то, что происходит в большинстве приложений, но я не знаю, потому что никогда раньше не делал ничего подобного и не делаю у меня большой опыт, поэтому было бы здорово, если бы он помог мне подробно, по крайней мере, подкрепив это кодом.
вот коды, которые я сделал.
экран, на котором мне нужна информация о пользователе, номер телефона , имя, фамилия и т. д.
@Composable
fun UserFormScreenRoute(
sharedViewModel: SharedViewModel,
viewModel: UserFormViewModel = hiltViewModel()
) {
val state by viewModel.state.collectAsState()
UserFormScreen(
sharedViewModel = sharedViewModel,
state = state,
postRegister = viewModel::postRegister,
...
)
}
@Composable
fun UserFormScreen(
sharedViewModel: SharedViewModel,
state: UserFormScreenState,
postRegister: (RegisterUiModel) -> Unit,
...
) {
.
.
. // other informations and other components etc. it is not very important
DYTLoginAndContinueButton(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
text = stringResource(id = R.string.devam),
navController = null,
route = null,
enabled = buttonEnabled(state)
) {
postRegister(
RegisterUiModel(
email = "",
phone = getOnlyPhoneNumber(),
name = state.name,
birthdate = state.birthDate,
gender = state.gender.get(),
password = state.password,
eatingHabit = sharedViewModel.registerData?.eatingHabit,
wellnessGoal = sharedViewModel.registerData?.wellnessGoal,
token = "xxx",
dialCode = "90"//state.phoneCode.substring(1) ?: "90"
)
)
}
}
DYTLoginAndContinueButton — это кнопка. он перемещается по экрану кода подтверждения, когда пользователь нажимает эту кнопку, и отправляет номер телефона пользователя в службу для отправки пользователю SMS-кода.
прослушайте экран подтверждения моего кода
@Composable
fun VerificationPhoneCodeRoute(
navHostController: NavHostController,
viewModel: VerificationPhoneCodeViewModel = hiltViewModel()
) {
val state by viewModel.state.collectAsState()
VerificationPhoneCodeScreen(
navHostController = navHostController,
state = state,
onChangeOtpValue = viewModel::onChangeOtpValue,
verificationSmsCode = viewModel::verificationSmsCode,
setError = viewModel::setError,
)
}
@Composable
fun VerificationPhoneCodeScreen(
navHostController: NavHostController,
state: VerificationPhoneCodeScreenState,
onChangeOtpValue: (String) -> Unit,
verificationSmsCode: (String) -> Unit,
setError: (Boolean) -> Unit
) {
if (state.error) {
CustomAlertDialog(
text = "error!",
ButtonText = "okey",
onChangeError = {
setError(it)
}
)
}
Scaffold(
topBar = {
BackPopUp(
navController = navHostController,
route = RegisterScreen.SignUpUserFormScreen.route
)
},
backgroundColor = Color.Transparent
) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top
) {
Text(
textAlign = TextAlign.Center,
modifier = Modifier.padding(10.dp),
text = please enter your sms code below field,
style = MaterialTheme.typography.subtitle1
)
OtpTextField(
otpText = state.otpValue,
otpVerificationStatus = state.otpVerificationStatus,
onOtpTextChange = { value, otpInputFilled ->
onChangeOtpValue(value)
if (otpInputFilled) {
verificationSmsCode(value)
}
}
)
Text(
modifier = Modifier.align(Alignment.CenterHorizontally),
text = state.phoneNumber
)
}
}
}
OtpTextField
@Composable
fun OtpTextField(
modifier: Modifier = Modifier,
otpVerificationStatus: OtpVerificationStatus,
otpText: String,
otpCount: Int = 4,
onOtpTextChange: (String, Boolean) -> Unit
) {
LaunchedEffect(Unit) {
if (otpText.length > otpCount) {
throw IllegalArgumentException("Otp text value must not have more than otpCount: $otpCount characters")
}
}
BasicTextField(
modifier = modifier,
value = TextFieldValue(otpText, selection = TextRange(otpText.length)),
onValueChange = {
if (it.text.length
CharView(
index = index,
text = otpText,
otpVerificationStatus
)
Spacer(modifier = Modifier.width(8.dp))
}
}
}
)
}
@Composable
private fun CharView(
index: Int,
text: String,
otpVerificationStatus: OtpVerificationStatus
) {
val isFocused = text.length == index
val char = when {
index == text.length -> "0"
index > text.length -> ""
else -> text[index].toString()
}
var focusedColor = MaterialTheme.colors.DYTThemeColor
var nonFocusedColor = MaterialTheme.colors.grayColor
when(otpVerificationStatus){
OtpVerificationStatus.DEFAULT -> {
focusedColor = MaterialTheme.colors.DYTThemeColor
nonFocusedColor = MaterialTheme.colors.grayColor
}
OtpVerificationStatus.VERIFICATION_TRUE -> {
focusedColor = DYTGreenColor
nonFocusedColor = DYTGreenColor
}
OtpVerificationStatus.VERIFICATION_FALSE -> {
focusedColor = red_color
nonFocusedColor = red_color
}
}
Text(
modifier = Modifier
.size(50.dp, 60.dp)
.border(
2.dp, when {
isFocused -> focusedColor
else -> nonFocusedColor
}, RoundedCornerShape(8.dp)
)
.padding(2.dp)
.offset(y = 15.dp),
text = char,
style = MaterialTheme.typography.h4,
color = MaterialTheme.colors.DYTThemeColor,
textAlign = TextAlign.Center
)
}
MySMSBroadcastReceiver
class MySMSBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
val extras = intent.extras
val status = extras?.get(SmsRetriever.EXTRA_STATUS) as Status
when (status.statusCode) {
CommonStatusCodes.SUCCESS -> {
val message = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
println("SMS CODE MESSAGE -> "+message)
}
CommonStatusCodes.TIMEOUT -> {
}
}
}
}
}
Манифест
Я добавил этот код в тег приложения манифеста
Build.gradle
Я тоже добавил их в свои зависимости build.gradle
implementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
implementation 'com.google.android.gms:play-services-auth:20.4.1'
MainActivity
Я подумал, что было бы правильно добавить mainactivity, потому что я не знаю, куда установить эту часть .
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
lateinit var navHostController: NavHostController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val client = SmsRetriever.getClient(this)
val task: Task = client.startSmsRetriever()
task.addOnSuccessListener(OnSuccessListener {
})
task.addOnFailureListener(OnFailureListener {
})
setContent {
DiyetkolikTheme {
navHostController = rememberNavController()
Surface(
modifier = Modifier
.fillMaxSize()
) {
RootNavGraph(navHostController = navHostController)
}
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/762 ... -in-kotlin
Как использовать API Google SMS Retiver с составлением реактивного ранца в Котлине? ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Проблема с модификацией mutableStateFlow и составлением реактивного ранца
Anonymous » » в форуме Android - 0 Ответы
- 29 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Аналитика Google Firebase не работает при составлении реактивного ранца
Anonymous » » в форуме Android - 0 Ответы
- 17 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как использовать обновления в приложении в создании реактивного ранца
Anonymous » » в форуме Android - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Anonymous
-