android 如何使用警报管理器每小时从网页获取数据?

How to get data from web page every hour using alarm manager in android?

我正在制作一个应用程序,它需要从网页中的 html 元素获取数据,并在应用程序未 运行 时每小时发送一个包含数据的通知。为此,我使用了 AlarmManager。在我的 AlarmReceiver class 然后我尝试使用 JSoup 连接到网站。

    public class AlarmReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intentt) {
        try {
            Document doc = Jsoup.connect(URL).get();
        } catch (IOException e) {
            e.printStackTrace();
        }  

这给了我例外NetworkOnMainThreadException

所以我尝试了这个解决方案:

    final WebView w = new WebView(context);
    w.loadUrl(URL);
    WebSettings webSettings = w.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setDomStorageEnabled(true);
    webSettings.setDefaultTextEncodingName("utf-8");
    webView.setWebViewClient(new WebViewClient() {
        public void onPageFinished(WebView view, String url) {
            w.evaluateJavascript("(function() { return document.getElementById('app_notification_id').innerHTML;})()", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                  ...

这次我在调试器中看到 OnPageFinished 中的代码甚至没有执行,尽管当我在 MainActivity 中尝试它时应用程序处于活动状态并且 运行此代码工作正常。

我怎样才能实现我的目标?是否有其他方法可行,或者我的代码有误?

使用 JobScheduler 而不是 AlarmManager。 AlarmManager 已经过时。查看 link 了解更多信息。

https://www.vogella.com/tutorials/AndroidTaskScheduling/article.html

onReceive() BroadcastReceiver 的方法在主应用程序线程上被调用,你应该 不要做磁盘 I/O 或网络 I/O 在主应用程序线程上。这就是你得到 NetworkOnMainThreadException 的原因。将该 HTTP 代码移至另一个 IntentService,然后调用 -

startService(intentService)

onReceive() 方法BroadcastReceiver

此外,您不能在接收器中添加 WebView,因为它需要 activity 引用,因为您仅从上下文引用中添加它。只需应用上述解决方案即可。

我找到了更好的解决方案来解决我的问题。我能够创建一个新的 webview 并使用 OnPageFinished,这是我试图通过将这些行添加到代码中来实现的

Handler handler = new Handler(Looper.getMainLooper());
try {
    handler.post(
            new Runnable() {
                @Override
                public void run() {
                    final WebView w = new WebView(context);
                    w.loadUrl(url);
                    WebSettings webSettings = w.getSettings();
                    webSettings.setJavaScriptEnabled(true);
                    webSettings.setDomStorageEnabled(true);
                    webSettings.setDefaultTextEncodingName("utf-8");
                    w.setWebViewClient(new WebViewClient() {
                       public void onPageFinished(WebView view, String url) {
                            w.evaluateJavascript("(function() { return document.getElementById('app_notification_id').innerHTML;})()", new ValueCallback<String>() {
                                ...