Вибратор должен активироваться при любом состоянии телефона и приложения. : телефон проснулся и приложение на переднем плане, телефон в состоянии ожидания и приложение в фоновом режиме, другое приложение перегружает процессор... Я просто хочу сказать пользователю: «Пожалуйста, не закрывайте приложение, а делайте с ним все, что хотите». ваш телефон"
Для этого я использую (см. мой код ниже):
- A Служба переднего плана с разрешением на телефонный звонок
- Часы NTP, которые помогают мне компенсировать отклонение часов локальной системы
- Функция alarmManager.setExactAndAllowWhileIdle() для установки будильника
Видите ли вы какие-нибудь другие процедуры или инструменты Android, которые мне следует использовать, чтобы сделать срабатывание вибратора ОЧЕНЬ точным? Спасибо!
...
...
...
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
Project4Theme {
ScheduleVibrationAlarm(context = this)
}
}
}
}
}
@Composable
fun ScheduleVibrationAlarm(context: Context) {
var calendar by remember { mutableStateOf(Calendar.getInstance()) }
var timeDifference by remember { mutableStateOf(null) }
Column(
) {
Text(text = "Schedule Vibration Alarm")
Button(onClick = {
Thread {
try {
// Get NTP time
val ntpClient = NTPUDPClient()
ntpClient.defaultTimeout = 10000
val inetAddress = InetAddress.getByName("pool.ntp.org")
val timeInfo = ntpClient.getTime(inetAddress)
timeInfo.computeDetails()
// Get local system time
val localTime = System.currentTimeMillis()
// Get difference
val ntpTime = timeInfo.message.transmitTimeStamp.time
timeDifference = ntpTime - localTime
// Set vibrator alarm time (17:00 today)
calendar.set(Calendar.HOUR_OF_DAY, 17)
calendar.set(Calendar.MINUTE, 0)
calendar.set(Calendar.SECOND, 0)
calendar.set(Calendar.MILLISECOND, (timeDifference!!.toInt()*-1))
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent1 = Intent(context, AlarmReceiver::class.java)
val pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent1)
} catch (e: Exception) {
Log.e("NTP", "Fail on NTP get", e)
}
}.start()
}) {
Text(text = "Set Vibrator Alarm")
}
}
}
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val vibrationIntent = Intent(context, VibrationService::class.java)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(vibrationIntent)
} else {
context.startService(vibrationIntent)
}
}
}
class VibrationService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// Create a notif (if not, Android kill foreground service
createNotificationChannel()
val notification = NotificationCompat.Builder(this, "VibrationServiceChannel")
.setContentTitle("Vibrator")
.setContentText("Vibrator is running ")
.build()
// Start foreground service
startForeground(1, notification)
// Vibrate
val vibrator = getSystemService(VIBRATOR_SERVICE) as Vibrator
vibrator.vibrate(1000)
// Stop service
stopSelf()
return START_NOT_STICKY
}
override fun onBind(intent: Intent?): IBinder? = null
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(
"VibrationServiceChannel",
"Vibration Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(serviceChannel)
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... -the-phone
Мобильная версия