Android Question java.lang.StringIndexOutOfBoundsException

sdesan

Member
Licensed User
This is my problem.
I use a web pages to record data in an access database via odbc and classica asp pages.
In b4a project i collect some data and then use this code
B4X:
'recording
 req.InitializeGet("http://localhost/rec_data.asp?secret=mypwd&idclie="&idcli&"&ragso="&encodedRagsoc&"&event="&encodedEvent&"&note="&encodedNote&"&date_d="&dated&"&time_d="&timed&"&tecni="&usertec)
    httpC.Execute(req, 1)
    ProgressDialogShow("Recording...")  
    label2.Text="Ok"
All data are correctly saved on database but i receive this error StringIndexOutOfBoundsException

B4X:
java.lang.StringIndexOutOfBoundsException


    at java.lang.String.substring(String.java:1579)
    at OneGest.Web.main._httpc_responsesuccess(main.java:606)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.BA$3.run(BA.java:320)
    at android.os.Handler.handleCallback(Handler.java:587)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.StringIndexOutOfBoundsException

and i'm unable to debug the problem (i'm trying from 3 days with no success).
Any ideas about?
Thank you
 

DonManfred

Expert
Licensed User
post the cod4e from httpclient_sccess. Seems that the problem is inside this sub
 
Upvote 0

sdesan

Member
Licensed User
Thank you for the answers. After reading i have best focused my problem (that depens only on my lack of knowledge on httputils)
So:
i start with a data reading from web pages
B4X:
whoisname= su.EncodeUrl(whocli.text, "UTF8")
        req.InitializeGet("http://localhost/gestweb.php?secret=mypwd&name="&whoisname)
        req.Timeout = 10000 'set timeout to 10 seconds
        httpC.Execute(req, 1)
        ProgressDialogShow("Retrieving data...")
This request works fine whith this code
B4X:
Sub httpC_ResponseSuccess (Response As HttpResponse, TaskId As Int)
    Dim result As String
    positio=0
    result = Response.GetString("UTF8")
    File.WriteString(File.DirInternalCache, "scores.sco",result)
    reader.Initialize(File.OpenInput(File.DirInternalCache, "scores.sco"))
    Dim line As String
    line = reader.ReadLine
    Do While line <> Null
        positio=line.IndexOf(";")
        ClieSpinner.Add(line.SubString(positio+1))
        idlistacliente.Add(line.SubString2(0,positio))
        line = reader.ReadLine
        positio=0
    Loop
    reader.Close
    ProgressDialogHide
End Sub

My error i think has been this:
in the recording section i write
B4X:
'recording
req.InitializeGet("http://localhost/rec_data.asp?secret=mypwd&idclie="&idcli&"&ragso="&encodedRagsoc&"&event="&encodedEvent&"&note="&encodedNote&"&date_d="&dated&"&time_d="&timed&"&tecni="&usertec)
    httpC.Execute(req, 1)
    ProgressDialogShow("Recording...") 
    label2.Text="Ok"
using another time
B4X:
httpC.Execute(req, 1)
so telling to code to resend TaskID = 1
I have modified the code in this
B4X:
'recording
req.InitializeGet("http://localhost/rec_data.asp?secret=mypwd&idclie="&idcli&"&ragso="&encodedRagsoc&"&event="&encodedEvent&"&note="&encodedNote&"&date_d="&dated&"&time_d="&timed&"&tecni="&usertec)
    httpC.Execute(req, 2)
    ProgressDialogShow("Recording...") 
    label2.Text="Ok"
and this
B4X:
Sub httpC_ResponseSuccess (Response As HttpResponse, TaskId As Int)
If TaskId=1 Then
    Dim result As String
    positio=0
    result = Response.GetString("UTF8")
    File.WriteString(File.DirInternalCache, "scores.sco",result)
    reader.Initialize(File.OpenInput(File.DirInternalCache, "scores.sco"))
    Dim line As String
    line = reader.ReadLine
    Do While line <> Null
        positio=line.IndexOf(";")
        ClieSpinner.Add(line.SubString(positio+1))
        idlistacliente.Add(line.SubString2(0,positio))
        line = reader.ReadLine
        positio=0
    Loop
    reader.Close
    ProgressDialogHide
End If
If TaskId=2 Then
    ProgressDialogHide
    label2.Text="Data recorded."
End If
End Sub

And in this manner there is no error.
So is this the correct/best way or is possible to use a different approach to the problem.
Thank you again
 
Upvote 0

jmon

Well-Known Member
Licensed User
looks like your error comes from here:
B4X:
idlistacliente.Add(line.SubString2(0,positio))

reading from your error, you can see that it is coming from "substring"
B4X:
java.lang.StringIndexOutOfBoundsException
at java.lang.String.substring(String.java:1579)

So it means that "positio" is trying to read a character at a position higher than the number of characters in your string. You should first test if your string.length is higher or equal to positio and then proceed if it's true.

Second reason, is that "indexOf" returns -1 if cannot find the character requested. So your error be cause by trying to read a substring at position(0, -1)
You should test that :
B4X:
if positio > -1 then
    '....
end if
 
Upvote 0

sdesan

Member
Licensed User
Thank you jmon.
Your interpretation is correct. The problem was in two call to httpC_ResponseSuccess with the same TaskId, where the second one don't have a substring and a position to analize.
With the if condition above all now works
Thank you for your time
Have a nice day
 
Upvote 0
Top