【问题标题】:Android: way to detect if the user changed system time while the app was stoppedAndroid:在应用停止时检测用户是否更改系统时间的方法
【发布时间】:2015-06-05 10:26:26
【问题描述】:

我正在为某公司内部开发一个Android应用程序,它需要记录员工的工作时间。因此,系统时间的工作至关重要。我的应用程序非常需要知道用户何时更改系统时间。大不了,你说,看看这个:Is there a way to detect when the user has changed the clock time on their device?

问题是用户可能会通过在更改时间之前强制停止应用程序来绕过该解决方案。然后应用程序将不会收到系统通知,这在此处进行了精彩描述:https://stackoverflow.com/a/19856367/1309803

我不介意在下次启动应用程序时检查它,但我怎么可能知道用户是否更改了时间?我知道 SystemClock.elapsedRealtime()。如果用户没有重新启动设备,我可以根据这些值的增量来计算时间偏移,但这是我不确定的。我的应用程序订阅了 BOOT_COMPLETED 事件,但在应用程序处于停止状态时也不会收到该事件。

而且,总而言之,那家公司的员工应该在没有网络访问权限的情况下工作,所以我不能依赖 Web 服务器。那么还有其他可能的方法吗?

【问题讨论】:

  • 您是否尝试过将服务与 onStartCommand() 中的 START_STICKY 结合使用来实现时间变化观察的“无法杀死”环境?
  • @Videdenta 您能否稍微扩展您的建议?我无法想象该服务如何帮助应对强制停止场景。
  • 即使在应用程序关闭后,服务也会运行。当然你也可以通过TaskManager强制关闭Service,但是使用START_STICKY属性会重新创建Service。
  • @Videdenta 我的问题与通过任务管理器强制关闭完全有关,否则广播接收器将仍然能够接收意图。在这种(强制关闭)情况下,START_STICKY 似乎不相关(stackoverflow.com/a/9441795/1309803)。但是,即使它确实重新创建了服务,我怎么知道系统时间在它结束时是否发生了变化?

标签: android time notifications


【解决方案1】:

从第三方服务器获取时间在大多数情况下并不可靠,其中一些是付费服务。

如果你想得到准确的时间并用手机检查它是否正确,无论方法如何,你都可以使用以下简单的技巧来获取实际时间。

private class GetActualTime extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {
            try {
                HttpURLConnection urlConnection = null;
                StringBuilder result = new StringBuilder();
                try {
                    URL url = new URL(urls[0]);
                    urlConnection = (HttpURLConnection) url.openConnection();
                    int code = urlConnection.getResponseCode();
                    if (code == 200) {
                        InputStream in = new BufferedInputStream(urlConnection.getInputStream());
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
                        String line = "";
                        while ((line = bufferedReader.readLine()) != null)
                        result.append(line);
                        in.close();
                    }
                        else {
                        return "error on fetching";
                    }
                    return result.toString();
                } catch (MalformedURLException e) {
                    return "malformed URL";
                } catch (IOException e) {
                   return "io exception";
                } finally {
                    if (urlConnection != null) {urlConnection.disconnect();
                    }
                }
            } catch (Exception e) { return "null"; }
        }

        @Override
        protected void onPostExecute(String time) {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat mdformat = new SimpleDateFormat("h:mm");
            String times =  mdformat.format(calendar.getTime());
            try {
                String areatime = time.substring(time.indexOf(String.valueOf(times)), time.indexOf(String.valueOf(times)) + 5).trim(); 
                        Toast.makeText(this, "The actual time is " + areatime, Toast.LENGTH_SHORT).show();

            }
            catch(IndexOutOfBoundsException e){
                        Toast.makeText(this, "Mobile time is not same as Internet time", Toast.LENGTH_SHORT).show();
                }
            }


        }

    }

在onCreate()中调用类;

new GetActualTime().execute("https://www.google.com/search?q=time");

所以这实际上是从 Google 获得时间。这在我的项目中非常有效。为了检查系统时间是否错误,可以使用这个技巧。您可以信任 Google,而不是依赖时间服务器。

由于它在检查中更加敏感,即使提前一分钟或滞后一分钟也会捕获异常。如果你想处理它,你可以自定义代码。

【讨论】:

  • 与其对多个问题发布相同的答案,不如将问题标记为重复(一旦您获得了足够的声誉)。
  • 更简单的方法
猜你喜欢
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2012-10-07
  • 1970-01-01
  • 2011-07-30
相关资源
最近更新 更多