Pull to refresh

Comments 25

В этом посте прекрасно все. От постановки задачи до решения. Самое главное менеджер доволен, в этом и есть цель любого проекта.
Все делается с какой-то целью. Есть приложение для постановки задач, которе должно работать оффлайн. В них есть роль менеджера и исполнителя. Так вот, чтобы исполнитель не жульничал со временем, делается такая вещь.
нельзя, время должно фиксироваться в момент завершения задачи, а не в момент отправки на сервер.
DRM, чтоб его.

Я пользуюсь несколькими сервисами предоставляющими по подписке видео для просмотра в оффлайне. Т.е. скачал кино или сериал, потом в метро, в отпуске или на даче смотришь.

Всё вроде ОК, но правообладатели и/или владельцы сервиса ставят ограничения типа:
1. Устройство должно минимум раз в неделю выходить в интернет
2. Фильмы можно хранить на устройстве 7, 14 или 28 дней
3. С момента начала просмотра фильм можно смотреть неограниченно в течение 48 часов, потом он удаляется.
4. По истечении подписки всё удаляется.
5. Просмотр разрешён только в одной стране

Сперва я этого не знал и удивлялся, почему вдруг пропадают фильмы и сериалы, которых я залил на планшет с расчётом посмотреть их в течение недели, ну и проверил каждую серию, воспроизводится ли.

Обычно помогает обычная перемотка времени назад, а чтобы программа не вела лог с временем, устройство следует переводить в режим самолёта отключая интернет и GPS, процесс приложения после просмотра нужно убивать, а при следующем просмотре выставлять время закрытия приложения. К счастью, они пока ещё не догадываются, или у них нет возможности узнавать время другим способом, кроме системных часов.
> Обычно помогает обычная перемотка времени назад, а чтобы программа не вела лог с временем, устройство следует переводить в режим самолёта отключая интернет и GPS, процесс приложения после просмотра нужно убивать, а при следующем просмотре выставлять время закрытия приложения.

И они еще удивляются, почему пиратство процветает
С моей точки зрения, пиратство процветает по другой причине. Есть 2 понятия: удобство установки и качество продукта.

1. Мне удобнее скачать игру в стиме (пусть и заплатив при этом), чем лазать по торрентам/копипастить ключи из кейгенов/любой другой способ.
2. Я купил IntelliJ IDEA потому, что ребята сделали очень качественный продукт, который стоит своих денег. И это при том, что крякнутые версии вполне себе существуют.

А вот платить за сомнительное приложение, которое установить не проще, чем сломанное, бессмысленно.
Интересно, а можно вопрос: Я правильно понимаю, что перевод назад можно поймать только если пользователь переведет время до последнего запуска? То есть, выключили программу на два дня, перевели на полтора — программа будет думать что прошло только полдня?
Насколько помню в виндовс была такая методика — как проверка самых часто используемых временных каталогов (вроде tmp) на последнее время файлов. Вот тогда практически невозможно обмануть переводом назад, не знаю насколько такое легко реализовать на андроиде.
Да, если перевести время в момент между включением системы и запуском ресивера, то выйдет так. но это только при перезагрузке устройства.
Перевод вперед нас не особо интересовал, да и отследить его весьма трудно.

А вот в играх как раз наоборот, т.к. перевод времени вперед позволяет «ускорять» постройку зданий :)
да, но данный метод обходится только если перевести время в момент включения приложения до запуска ресивера, не все пользователи на это способны.
дуалбут, функция установки времени в рековери, как я понимаю надёжные способы обмануть вашу систему.
Не защищено от взлома (обхода) особо продвинутыми юзерами. Если уж на то пошло, ломается все. Рассчитано на среднестатистического обывателя.

Ага, все верно
не пробовали принимать во внимание время прошедшее с момента загрузки устройства? В сочетании с текущей датой можно делать довольно далеко идущие выводы и даже про перевод времени вперед. при введении логики которая способна отдавать возможность текущей даты принимая во внимание прошлые показания аптайма и даты можно делать вывод о том можно ли доверять текущему времени или воспользоваться внутренним таймером.
чтобы это обойти надо будет неплохо заморочаться подбивая перезагрузку с моментом запуска приложения и моментом перевода времени.
Хм, про время старта системы думал, но пока что такой логики вполне хватает, возможно в будущем сделаю и это.
Есть одна особенность, столкнулся с ней недавно. Функция setRepeating начиная с KitKat работает неточно, т.е., аларм может в Вашем случае вызваться в промежутки +[1;2) c. Это может потенциально почти в 2 раза снизить погрешность измерений.
Странно, не замечал. Спасибо, понаблюдаю.
Но в приложении, где это работает, связь с сервером осуществляется достаточно часто, поэтому время будет постоянно корректироваться.
Я вообще не понимаю что вы написали. setRepeating alarm вообще может не вызываться если девайс спит (то что ваш не спит, это другой вопрос). System.currentTimeMillis() и RTC_WAKEUP это wall clock, то есть я переведу время на 10с назад и все аларм сработает на 10с раньше, чем должен. я вообще могу не трогая ваш код постоянно ускорять или замедлять ход времени у вас написав простенький скрипт. Еще ваш времямер будет работать только если приложение не на карточке. вы всегда делаете incrementTimeAndSaveSystemTime на фиксированный интервал, и пофиг что ночью был спил и мы не вызывались часов 7 подрят, мы просто приплюсуем +=TIME_PERIOD. А зачем вы всегда используете currentTimeMillis? То есть я честный пользователь, приехал к бабушке в другой часовой пояс, а мне ваша система все блокирует и говорит что я хакет и пытаюсь вас обмануть и перевожу часы назад? Почему бы не использовать nanoTime и аларм шедьюлить тоже в nanoTime?
И еще в новых андроидах есть elapsedRealtimeNanos то есть почти все что вы сделали, можно выкинуть, а в старых есть почти полноценная замена uptimeMillis. Его на нерутованном девайсе уже хрен изменишь.
Вот описание параметра RTC_WAKEUP
Alarm time in System.currentTimeMillis() (wall clock time in UTC), which will wake up the device when it goes off.

И если кратко, то событие произойдет, даже когда телефон в спящем режиме(режим ожидания).

Что касается System.currentTimeMillis(), то оно возвращает время в UTC, а значит не зависит от часового пояса.

то есть я переведу время на 10с назад и все аларм сработает на 10с раньше, чем должен

Про перевод времени сложнее, нет обоснованного ответа. Но практические тесты показали, что все отлично работает
да ваша правда, стормозил. теперь наш девайс еще и просыпается каждые 30 секунд. ну ладно у нас одно такое приложение. а теперь ставим 10 таких приложений с вашим подходом… да это какоето зло, постоянно просыпаемся, пишем в файловую систему. а если девайс у нас слабенький и андоид решает выгрузить наше приложение… то создаем процесс, грузим в него VM, стартуем потоки, инициализируем все, ставим маленький флажок (читаем и пишем на файловую систему) потом все это прибиваем, выгружаем… а теперь поставим 20 таких приложений, тут уже и хороший девайс начнет прибивать аппы и постоянно их создавать чтобы обработать аларм…
В моем случае промежутки времени были намного больше (30 минут). Я и заметил это только из-за того, что событие не происходило в указанное время. Посмотрите в документацию (setInexactRepeating и setRepeating note), там сейчас это уже явно прописано:
Your alarm's first trigger will not be before the requested time, but it might not occur for almost a full interval after that time. In addition, while the overall period of the repeating alarm will be as requested, the time between any two successive firings of the alarm may vary. If your application demands very low jitter, use one-shot alarms with an appropriate window instead; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent).

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
Sign up to leave a comment.