-1

Every time I click a button, my app closes. This only started happening after I put the code I was executing inside the onclick event. Before that it was just a toast, and that worked fine.

I can't make heads or tails from the debug output:

Connected to the target VM, address: 'localhost:8600', transport: 'socket'
W/Settings: Setting device_provisioned has moved from android.provider.Settings.Secure to android.provider.Settings.Global.
V/HiTouch_HiTouchSensor: User setup is finished.
I/HwViewRootImpl: removeInvalidNode all the node in jank list is out of time
V/AudioManager: querySoundEffectsEnabled...
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
I/BlockMonitor: dispatchingThrewException In MainThread
D/AndroidRuntime: Shutting down VM
I/QarthLog: [PatchStore] createDisableExceptionQarthFile
    [PatchStore] create disable file for com.example.dsfrs_soup_news uid is 10507
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.dsfrs_soup_news, PID: 22361
    java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:523)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101) 
     Caused by: java.io.IOException: Cleartext HTTP traffic to www.dsfire.gov.uk not permitted
        at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:124)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:462)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
        at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:732)
        at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:707)
        at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:297)
        at org.jsoup.helper.HttpConnection.get(HttpConnection.java:286)
        at com.example.dsfrs_soup_news.MainActivity$onCreate$1.onClick(MainActivity.kt:21)
        at android.view.View.performClick(View.java:7189)
        at android.view.View.performClickInternal(View.java:7163)
        at android.view.View.access$3500(View.java:821)
        at android.view.View$PerformClick.run(View.java:27579)
        at android.os.Handler.handleCallback(Handler.java:888)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:213)
        at android.app.ActivityThread.main(ActivityThread.java:8147)
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101) 
I/Process: Sending signal. PID: 22361 SIG: 9
Disconnected from the target VM, address: 'localhost:8600', transport: 'socket'

This is my main activity code:

package com.example.dsfrs_soup_news

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import org.jsoup.Jsoup
import java.io.IOException

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        try{
        // get reference to button
        val BtnGo = findViewById(R.id.BtnGo) as Button
        val TxtResults: TextView = findViewById(R.id.TxtResults) as TextView
// set on-click listener
        BtnGo.setOnClickListener {
            Toast.makeText(this@MainActivity, "You clicked me.", Toast.LENGTH_SHORT).show()
        val doc = Jsoup.connect("http//www.dsfire.gov.uk/News/Newsdesk/IncidentsPast7days.cfm?siteCategoryId=3&T1ID=26&T2ID=35").get()
        val links = doc.select("tr td:first-of-type a")
            .map { col -> col.attr("href") } //href gets each link
        //for every link display the gumf, ................consider just showing todays, exit loop once total number of incidents has been displayed
        links.forEach { links ->
            //println("http://www.dsfire.gov.uk/News/Newsdesk/$links \n")
            TxtResults.append("http://www.dsfire.gov.uk/News/Newsdesk/$links \n")
            // work with each link, get details from incident page
            val sIncident = Jsoup.connect("http://www.dsfire.gov.uk/News/Newsdesk/$links").get()
            var aLLDeetz = sIncident.select("td").toString() //convert to string to allow tidying
            //got all the details of the shout, now replace useless charecters
            aLLDeetz = aLLDeetz.replace("<td>", "")
            aLLDeetz = aLLDeetz.replace("</td>", "")
            aLLDeetz = aLLDeetz.replace("<td width=\"259\">", "")
            aLLDeetz = aLLDeetz.replace(":\\n", ": ")
            aLLDeetz = aLLDeetz.trim()
            //display results
            TxtResults.append("Icident Details are: \n  $aLLDeetz")
            //println(message = "Icident Details are: \n $aLLDeetz")
            //get all information in the incident summary and convert to string for cleaning
            var IncSumm = sIncident.getElementById("IncidentDetailContainer").toString()
            //clean useless chars out of string
            IncSumm = IncSumm.replace("<p>", "")
            IncSumm = IncSumm.replace("</div>", "")
            IncSumm = IncSumm.replace("<br></p>", "")
            IncSumm = IncSumm.replace("<br>", "")
            IncSumm = IncSumm.replace("<div id=\"IncidentDetailContainer\">", "")
            IncSumm = IncSumm.replace("&nbsp;</p>", "")
            IncSumm = IncSumm.replace("</p>", " ")
            IncSumm = IncSumm.replace("<p align=\"justify\">", "")
            IncSumm = IncSumm.replace("  ", "")
            //display results
            //println(IncSumm)
            TxtResults.append(IncSumm)
            finish() // other posts have put this in to stop forced close
        }
        }
    }  catch (e: IOException) {
            Toast.makeText(this@MainActivity, "Error is $e.", Toast.LENGTH_SHORT).show()
        }//try bracket
        
    }

}

My XML code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/results"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:id="@+id/TxtResults" android:layout_marginBottom="20dp" android:clickable="true"
            android:enabled="true" android:focusable="true"/>
    <Button
            android:text="@string/go"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/BtnGo" app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/TxtResults" app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent" android:enabled="true"/>

</androidx.constraintlayout.widget.ConstraintLayout>

And my gradle

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/results"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:id="@+id/TxtResults" android:layout_marginBottom="20dp" android:clickable="true"
            android:enabled="true" android:focusable="true"/>
    <Button
            android:text="@string/go"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/BtnGo" app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/TxtResults" app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent" android:enabled="true"/>

</androidx.constraintlayout.widget.ConstraintLayout>

When I started the app with just the button and the textview it worked fine displaying the toast.

As soon as I add the jsoup code to scrape a website it force closes when I click the button. I have debugged but I get nothing, and looking up the error, the only thing I could see was some where told to add finish().

It still happens so I figured I would ask people who would know.

I have done the project in Android Studio and had this issue too, but this code I have done using IntelliJ, created a new empty android project.

I know it's probably a stupid error and an easy fix, but this is my first app using jsoup (I tried skrape{it} but there is less documentation available and support.

I have edited the code to include my attempt to catch the error and I have also created the xml file as instructed and The app still just exits when i click the button.

Any other ideas?

Another thing I have just noticed, the app crashes after about 10 secs regardless of where i put the debug point, I barely have time to click step into before it quits.

Does this help shed light on my issue?

Ryan M
  • 18,333
  • 31
  • 67
  • 74
Raif Jackson
  • 59
  • 2
  • 11
  • 1
    The problem is right there in the stack trace: "Cleartext HTTP traffic to www.dsfire.gov.uk not permitted". JSoup has many methods that can throw IOExceptions for any number of reasons. You have to catch them or your app will crash under circumstances out of your control, like a website being unavailable, the user has a poor connection to the Internet, etc. – Tenfour04 Feb 24 '20 at 15:59
  • brilliant thanks, so just capture the error within my code and handle it accordingly. Just one thing, the code works perfectly when just in a kotlin file (normal kotlin project... not android), odd there should be a difference? isn't it? – Raif Jackson Feb 24 '20 at 16:11
  • Seems to be related to an Android security setting. I'm not familiar with this. So there are some workarounds. But you still need to catch IOExceptions for all the reasons they can happen that are not in your control. https://stackoverflow.com/questions/58022495/how-to-fix-cleartext-http-traffic-to-x-not-permitted – Tenfour04 Feb 24 '20 at 16:30
  • Does this answer your question? [Android 8: Cleartext HTTP traffic not permitted](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) – Ryan M Feb 24 '20 at 21:49
  • Hi, thanks for the suggestions, no that didn't change anything. But with a bit more searching and new coding (see edit) I am now getting a new error. saying I have got no protocol... but I do. I have tried more from what I have found about formatting the url but am still getting malformed protocol. can you help? – Raif Jackson Feb 26 '20 at 11:39
  • 2
    Don't encode the URL before connecting to it `java.net.MalformedURLException: no protocol: http%3A%2F%2Fwww.dsfire.gov.uk` And for your follow up question, don't do network requests on the main thread. – Eugen Pechanec Feb 26 '20 at 11:50
  • ok so ill get rid of the encoding part. As for your other suggestion, do you mean create a function to call from the main thread or something else? – Raif Jackson Feb 26 '20 at 13:28
  • I've rolled back an edit that completely changed the meaning of this question and invalidated its answer. If you have a new question, please ask it as a new question. – Ryan M Jun 23 '21 at 02:10

1 Answers1

3

@Tenfour04, has correctly point to the error to solve this. Create "xml" folder in "res" folder and create "network_security_config.xml" file

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">dsfire.gov.uk</domain> // add the domain name
    </domain-config>
</network-security-config>

In manifest under application tag, add

 android:networkSecurityConfig="@xml/network_security_config"

Hope this will help you!

Amanpreet Kaur
  • 440
  • 6
  • 13
  • i done that and also put in try and catch in, see my edited code but it still just closes the app when i click the button... have i tried to catch the exception properly? – Raif Jackson Feb 25 '20 at 10:30