Search code examples
androidjsouplogcatbackground-service

Android Studio JSoup Service


I run Android Studio 2.3.2 and I want to make an App that checks a Website for a String through a service. Doing this action normally with JSoup Library without a service for background running, works fine but trying it as a Service gives me errors in LogCat and it is not working properly.

public class BackgroundCheck extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String myurl = "http://s503426938.online.de/untis/Heute/subst_001.htm";
        try {
            // Connect to the web site
            Document document = Jsoup.connect(myurl).get();
            Element innerTable = document.getElementsByClass("mon_list").first();
            Elements rows = innerTable.select("tr");

            for (Element row : rows) {
                Elements cells = row.select("td");
                for (Element cell : cells) {
                    if (cell.className().equals("list")) {
                        if (cell.text().contains("10A")){
                            int notifID = 33;
                            int color = getResources().getColor(R.color.colorAccent);
                            long[] pattern = {0, 300, 200, 300};
                            PendingIntent settingsIntent = null;
                            String text = "es fällt bald etwas aus!";
                            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(BackgroundCheck.this)
                                    .setSmallIcon(R.drawable.ic_notifications_black_24dp)
                                    .setContentTitle("Vertretungsplan")
                                    .setContentText(text)
                                    .setColor(color)
                                    .addAction(new NotificationCompat.Action(R.drawable.ic_menu_manage, "Settings", settingsIntent))
                                    .setLights(color, 500, 500)
                                    .setDefaults(Notification.DEFAULT_SOUND)
                                    .setVibrate(pattern);

                            Notification notification = mBuilder.build();
                            Toast.makeText(BackgroundCheck.this,"10A",Toast.LENGTH_SHORT).show();
                            NotificationManagerCompat.from(BackgroundCheck.this).notify(notifID, notification);
                        }
                    }
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }






Toast.makeText(BackgroundCheck.this,"Test",Toast.LENGTH_SHORT).show(); //Works Fine
        Log.d("Vertretungsplan", "Checked: String");
        stopSelf();


        return super.onStartCommand(intent, flags, startId);
    }
}

In my MainActivity I added those lines to the OnCreate method in order to make the Background-Service run after starting up the app:

AlarmManager alarmManager = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
        Intent check = new  Intent(MainActivity.this, BackgroundCheck.class);
        PendingIntent startServicependingIntent = PendingIntent.getService(MainActivity.this,0,check,0);

Calendar calendar = Calendar.getInstance();
int intervall  = 1000*60;
calendar.setTimeInMillis(System.currentTimeMillis() + intervall);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),intervall,startServicependingIntent);`

Now Logcat throws following errors while trying to get the String from the Server in the table:

> 06-11 19:51:45.639 18293-18293/org.ddnss.jojeker.vertretungsplan D/Vertretungsplan: Checked: String
06-11 19:52:45.617 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err: android.os.NetworkOnMainThreadException
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:86)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at java.net.InetAddress.getAllByName(InetAddress.java:752)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:187)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:156)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:98)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:346)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:247)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:126)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:439)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:424)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:178)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.jsoup.helper.HttpConnection.get(HttpConnection.java:167)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at org.ddnss.jojeker.vertretungsplan.BackgroundCheck.onStartCommand(BackgroundCheck.java:35)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3366)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.app.ActivityThread.-wrap21(ActivityThread.java)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1612)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.os.Looper.loop(Looper.java:154)
06-11 19:52:45.618 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6236)
06-11 19:52:45.619 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
06-11 19:52:45.619 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
06-11 19:52:45.619 18293-18293/org.ddnss.jojeker.vertretungsplan W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)

Normally I use an AsyncTask to perform the action with JSoup but I don't think that it is necessary as a service. I used a Toast to make sure I didn't do any elementary mistakes. So my question is: is this the "right" way to get data as a Service through JSoup or am I doing something wrong by using it in this case. Is there another library which is easier to use or is JSoup the right choice for this kind of work?

I want to thank you in advance!


Solution

  • You still need to spawn a thread. Per the Android Services documentation:

    Caution: A service runs in the main thread of its hosting process; the service does not create its own thread and does not run in a separate process unless you specify otherwise. If your service is going to perform any CPU-intensive work or blocking operations, such as MP3 playback or networking, you should create a new thread within the service to complete that work.

    Also the problem is mentioned in the stacktrace:

    W/System.err: android.os.NetworkOnMainThreadException