mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
Date and time picker in Change time
This commit is contained in:
@@ -23,9 +23,12 @@ import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.FormatStyle
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
lateinit var getFile: ActivityResultLauncher<Intent>
|
||||
@@ -132,3 +135,10 @@ fun parseTimestamp(timestamp: Long): String {
|
||||
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault())
|
||||
return formatter.format(instant)
|
||||
}
|
||||
|
||||
val Long.humanReadableDate: String
|
||||
get() = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault()).format(Date(this))
|
||||
|
||||
val Long.humanReadableTime: String
|
||||
get() = SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(Date(this))
|
||||
|
||||
|
||||
@@ -45,15 +45,20 @@ import android.widget.Toast
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
@@ -63,14 +68,23 @@ import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.DatePicker
|
||||
import androidx.compose.material3.DatePickerDialog
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.SegmentedButton
|
||||
import androidx.compose.material3.SegmentedButtonDefaults
|
||||
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TimePicker
|
||||
import androidx.compose.material3.rememberDatePickerState
|
||||
import androidx.compose.material3.rememberTimePickerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
@@ -102,6 +116,7 @@ import com.bintianqi.owndroid.exportFilePath
|
||||
import com.bintianqi.owndroid.fileUriFlow
|
||||
import com.bintianqi.owndroid.formatFileSize
|
||||
import com.bintianqi.owndroid.getFile
|
||||
import com.bintianqi.owndroid.humanReadableDate
|
||||
import com.bintianqi.owndroid.prepareForNotification
|
||||
import com.bintianqi.owndroid.selectedPackage
|
||||
import com.bintianqi.owndroid.toggle
|
||||
@@ -360,6 +375,7 @@ fun Keyguard(navCtrl: NavHostController) {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@SuppressLint("NewApi")
|
||||
@Composable
|
||||
fun ChangeTime(navCtrl: NavHostController) {
|
||||
@@ -367,26 +383,108 @@ fun ChangeTime(navCtrl: NavHostController) {
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
val focusMgr = LocalFocusManager.current
|
||||
var inputTime by remember { mutableStateOf("") }
|
||||
val coroutine = rememberCoroutineScope()
|
||||
val pagerState = rememberPagerState { 2 }
|
||||
var manualInput by remember { mutableStateOf(false) }
|
||||
var inputTime by remember { mutableStateOf("")}
|
||||
var picker by remember { mutableIntStateOf(0) } //0:None, 1:DatePicker, 2:TimePicker
|
||||
val datePickerState = rememberDatePickerState()
|
||||
val timePickerState = rememberTimePickerState()
|
||||
val dateInteractionSource = remember { MutableInteractionSource() }
|
||||
val timeInteractionSource = remember { MutableInteractionSource() }
|
||||
if(dateInteractionSource.collectIsPressedAsState().value) picker = 1
|
||||
if(timeInteractionSource.collectIsPressedAsState().value) picker = 2
|
||||
val isInputLegal = (manualInput && (try { inputTime.toLong() } catch(_: Exception) { -1 }) >= 0) ||
|
||||
(!manualInput && datePickerState.selectedDateMillis != null)
|
||||
MyScaffold(R.string.change_time, 8.dp, navCtrl) {
|
||||
OutlinedTextField(
|
||||
value = inputTime,
|
||||
label = { Text(stringResource(R.string.time_unit_ms)) },
|
||||
onValueChange = { inputTime = it },
|
||||
supportingText = { Text(stringResource(R.string.info_change_time)) },
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
SingleChoiceSegmentedButtonRow(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 4.dp)
|
||||
) {
|
||||
SegmentedButton(
|
||||
selected = !manualInput, shape = SegmentedButtonDefaults.itemShape(0, 2),
|
||||
onClick = {
|
||||
manualInput = false
|
||||
coroutine.launch {
|
||||
pagerState.animateScrollToPage(0)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.selector))
|
||||
}
|
||||
SegmentedButton(
|
||||
selected = manualInput, shape = SegmentedButtonDefaults.itemShape(1, 2),
|
||||
onClick = {
|
||||
manualInput = true
|
||||
coroutine.launch {
|
||||
pagerState.animateScrollToPage(1)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.manually_input))
|
||||
}
|
||||
}
|
||||
HorizontalPager(
|
||||
state = pagerState, modifier = Modifier.height(140.dp).padding(top = 4.dp),
|
||||
verticalAlignment = Alignment.Top
|
||||
) { page ->
|
||||
if(page == 0) Column {
|
||||
OutlinedTextField(
|
||||
value = datePickerState.selectedDateMillis?.humanReadableDate ?: "",
|
||||
onValueChange = {}, readOnly = true,
|
||||
label = { Text(stringResource(R.string.date)) },
|
||||
interactionSource = dateInteractionSource,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = timePickerState.hour.toString() + ":" + timePickerState.minute.toString(),
|
||||
onValueChange = {}, readOnly = true,
|
||||
label = { Text(stringResource(R.string.time)) },
|
||||
interactionSource = timeInteractionSource,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
if(page == 1) OutlinedTextField(
|
||||
value = inputTime,
|
||||
label = { Text(stringResource(R.string.time_unit_ms)) },
|
||||
onValueChange = { inputTime = it },
|
||||
supportingText = { Text(stringResource(R.string.info_change_time)) },
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
Button(
|
||||
onClick = { dpm.setTime(receiver, inputTime.toLong()) },
|
||||
onClick = {
|
||||
val timeMillis = if(manualInput) inputTime.toLong()
|
||||
else datePickerState.selectedDateMillis!! + timePickerState.hour * 3600000 + timePickerState.minute * 60000
|
||||
val result = dpm.setTime(receiver, timeMillis)
|
||||
Toast.makeText(context, if(result) R.string.success else R.string.failed, Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = inputTime != ""
|
||||
enabled = isInputLegal
|
||||
) {
|
||||
Text(stringResource(R.string.apply))
|
||||
}
|
||||
}
|
||||
if(picker == 1) DatePickerDialog(
|
||||
confirmButton = {
|
||||
TextButton(onClick = { picker = 0; focusMgr.clearFocus() } ) {
|
||||
Text(stringResource(R.string.confirm))
|
||||
}
|
||||
},
|
||||
onDismissRequest = { picker = 0; focusMgr.clearFocus() }
|
||||
) {
|
||||
DatePicker(datePickerState)
|
||||
}
|
||||
if(picker == 2) AlertDialog(
|
||||
text = { TimePicker(timePickerState) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = { picker = 0; focusMgr.clearFocus() } ) {
|
||||
Text(stringResource(R.string.confirm))
|
||||
}
|
||||
},
|
||||
onDismissRequest = { picker = 0; focusMgr.clearFocus() }
|
||||
)
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
|
||||
@@ -143,8 +143,13 @@
|
||||
<string name="bug_report">Отчет об ошибке</string>
|
||||
<string name="confirm_bug_report">Запросить отчет об ошибке?</string>
|
||||
<string name="reboot">Перезагрузить</string>
|
||||
<string name="change_time">Change time</string> <!--TODO-->
|
||||
<string name="change_timezone">Change timezone</string> <!--TODO-->
|
||||
<!--TODO: the following 6 strings-->
|
||||
<string name="change_time">Change time</string>
|
||||
<string name="selector">Selector</string>
|
||||
<string name="manually_input">Manually input</string>
|
||||
<string name="date">Date</string>
|
||||
<string name="time">Time</string>
|
||||
<string name="change_timezone">Change timezone</string>
|
||||
<string name="timezone_id">Идентификатор часового пояса</string>
|
||||
<string name="disable_auto_time_zone_before_set">Автоматический часовой пояс должен быть отключен перед установкой пользовательского часового пояса.</string>
|
||||
<string name="permission_policy">Политика разрешений</string>
|
||||
|
||||
@@ -144,8 +144,13 @@
|
||||
<string name="bug_report">Hata raporu</string>
|
||||
<string name="confirm_bug_report">Hata raporu iste?</string>
|
||||
<string name="reboot">Yeniden başlat</string>
|
||||
<string name="change_time">Change time</string> <!--TODO-->
|
||||
<string name="change_timezone">Change timezone</string><!--TODO-->
|
||||
<!--TODO: the following 6 strings-->
|
||||
<string name="change_time">Change time</string>
|
||||
<string name="selector">Selector</string>
|
||||
<string name="manually_input">Manually input</string>
|
||||
<string name="date">Date</string>
|
||||
<string name="time">Time</string>
|
||||
<string name="change_timezone">Change timezone</string>
|
||||
<string name="timezone_id">Saat dilimi kimliği</string>
|
||||
<string name="disable_auto_time_zone_before_set">Özel bir saat dilimi ayarlamadan önce otomatik saat dilimi devre dışı bırakılmalıdır</string>
|
||||
<string name="permission_policy">İzin politikası</string>
|
||||
|
||||
@@ -140,6 +140,10 @@
|
||||
<string name="confirm_bug_report">请求错误报告?</string>
|
||||
<string name="reboot">重启</string>
|
||||
<string name="change_time">更改时间</string>
|
||||
<string name="selector">选择器</string>
|
||||
<string name="manually_input">手动输入</string>
|
||||
<string name="date">日期</string>
|
||||
<string name="time">时间</string>
|
||||
<string name="change_timezone">更改时区</string>
|
||||
<string name="timezone_id">时区ID</string>
|
||||
<string name="disable_auto_time_zone_before_set">在设置时区前需要关闭自动时区</string>
|
||||
|
||||
@@ -150,6 +150,10 @@
|
||||
<string name="confirm_bug_report">Request bug report?</string>
|
||||
<string name="reboot">Reboot</string>
|
||||
<string name="change_time">Change time</string>
|
||||
<string name="selector">Selector</string>
|
||||
<string name="manually_input">Manually input</string>
|
||||
<string name="date">Date</string>
|
||||
<string name="time">Time</string>
|
||||
<string name="change_timezone">Change timezone</string>
|
||||
<string name="timezone_id">Timezone ID</string>
|
||||
<string name="disable_auto_time_zone_before_set">Auto timezone should be disabled before set a custom timezone. </string>
|
||||
|
||||
Reference in New Issue
Block a user