Opening a BinaryStream is missing in Android?

Hi,

My Android app hangs when it tries to open a file using the BinaryStream.Open method. Checking the documentation, it reads the following for the open method:
“This method is not supported for Android.”. Fine, at least I know the reason of the hang.

I fail to find another method to read the file, although the Create command is well supported to write to the file.
What am I missing?

How does your code look like? It’s working here.

This is the Load function:

try
  Var f As FolderItem=GetPasswordFile(False)
  
  if f<>nil then 'not f.exists is taken care in the above function
    Var b As BinaryStream=BinaryStream.Open(f)
    EnteredPassword=b.Read(b.Length,Encodings.UTF8)
    b.Close
  end if
Catch e
  MessageBox e.ErrorNumber.ToString 'For debugging, but never went there
end try

(the password is currently saved clear, I’ll change that later)

And the GetPasswordFile function:

Public Function GetPasswordFile(ForSaving As Boolean) As FolderItem
  Var f As FolderItem
  
  'I already tried the commented folders below, not knowing where the issue lies:
  'f=SpecialFolder.ApplicationSupport
  'f=SpecialFolder.Caches
  f=SpecialFolder.Documents
  
  if f=nil then Return nil
  if not f.Exists then
    if not ForSaving then Return nil 'Folder doesn't exist
    f.CreateFolder
  end if
  f=f.Child(".com.amug.commliste.mdp") 'An invisible file
  
  if f=nil then Return nil 'Unexpected problem
  
  if (not f.Exists) and (not ForSaving) then Return nil 'File doesn't exist
  
  Return f
End Function

Yet the documentation says it shouldn’t :thinking: (Open isn’t supported on Android).
How does your working code look different to mine?

Thanks.

Which Xojo version do you use? Your shared code runs fine here. You should maybe clear your cache.

Theres also a FolderItem sample project which shows you BinaryStream.Open works.

Since the beginning, there’s something weird with this, because the same app works fine on my mother’s Android phone.
I don’t know Android enough to be aware of some kind of “antivirus” that may flag my app’s behaviour and make it hanging. Could this be the cause?

please rethink your GetPasswordFile method

normal a android app can read/write in his own sandbox enviroment, outside it need request permissions.

i would first care the folder exists and secondary the file.

in your load method is the part missing where f = nil

try
  Var f As FolderItem=File()
  if f<>nil then
  end if
Catch e
end try

should be

try
  Var f As FolderItem=File()
  if f=nil then
     raise error because you are in a try catch block
  else
     load binary file
  end if
Catch e
end try

Thanks for confirming.

The GetPasswordFile does that.

The “if f<>nil then” statement avoids using the file further if it’s nil. I’m not raising a further exception because I don’t need it (I just silently ignore the file when it doesn’t exist).

Anyway, my app hangs after the file is created (either just after saving it or when killing and re-opening the app (while attempting to read it)), not when the file doesn’t exist.

Thanks for your answer.

2023r4

Ok, this seems to confirm BinaryStream.Open is supported (the documentation states the opposite).
So why does the app hang on my phone?
Since MessageBox is asynchronous in Android, I can’t use that for debugging the real app. What other technique could I use, knowing debugging from Xojo isn’t an option for me?

Thanks for your answer.

Does System.DebugLog work on Android?

Can you open a textoutput stream instead? You can write binary to a textoutput stream. May be another data point in debugging your issue.

Thanks for the idea. It also hangs (I’ve only tried with SpecialFolder.Documents this time). Very weird.

I have the feeling this could be the line which could cause the error:

f=f.Child(".com.amug.commliste.mdp") 'An invisible file

Maybe Android has a problem with files starting with a dot?

The documentation doesn’t mention how to retrieve the output of this method; it only mentions Mac, Windows and Linux.
Would be great to use that, indeed.

I don’t think so, it’s rather me who has a problem with Android…

It turns out the issue isn’t about BinaryStream or files, but concerns delegates and/or AddressOf. I’m sorry to have bothered with the wrong issue; the fact that Xojo won’t debug Android apps on my computer (see my other thread, unsolved), neither in the simulator nor on a real device, makes me guessing a lot, trying slight modifications to my code, uploading the app to my website to install on my phone and watch whether the app hangs or not (and, when it hangs, I can’t see MessageBoxes to have a hint at which step it hung). It’s rather a nightmare.

My code use AddressOf a lot, so I have a module I can use in desktop, mobile and web. After lot of experimenting, I’ve found that these AddHandlers, AddressOf, Delegates and Timer.CallLater things hang at random times, often.

It’s puzzling: if I call the Init method alone, which contains AddHandler and AddressOf calls, the app seems to not hang. If I first load the saved password before calling Init, the Init method hangs.

Thanks to Ivan for having provided a solution to my non-working debugging for Android in Xojo, I’ve been able to spot on a bug in my project.
It was odd at first, because the debugger broke on a call to a method, with no parameter, with an OutOfBounds exception. That’s a Xojo issue. The exception was inside the called method but it wouldn’t break there nor stop at breakpoints.

In the offended code, there are two calls: string.left(1) and string.middle(1). It turns out that these throw an exception if the string is empty, unlike other platforms.

I’m writing all this in case someone else encounters the same weird behaviours.

Thanks for your help.

I thought those were supposed to throw an exception on all platforms.

Xojo/RB has always dealt with strings by returning empty results when an out of range condition happens (NthField, Left, etc.).
While they’re an array of characters, they are treated like a stream; it makes sense to me.

Xojo <> RB. The trend is toward exceptions. Maybe they haven’t gone there yet in order to extend the window of compatibility, but it is coming. They didn’t have to deal with backward compatibility for Mobile, but the rest will follow suit. I thought it had happened already.

I personally don’t hope so. I don’t like this trend. But, well, I don’t want to start a discussion on that subject, because they’ve already been done several times in the past, and I know each group (in favour/against) have strong arguments and the discussion won’t be constructive.

That would be stupid, IMO. An empty string is still a valid string. string.left(1) and string.middle(1), with string being empty, should simply return empty strings.