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!
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