Android Tutorial FileTransfer - Send and receive files with AsyncStreams

Status
Not open for further replies.
Newer example based on B4XSerializator: https://www.b4x.com/android/forum/threads/72149
AsyncStream v1.50 (part of RandomAccessFile library) includes support for sending and receiving streams of any size.

Unlike the regular write methods that send an array of bytes there is a new WriteStream method that takes an InputStream and sends it to the other size. This method is only supported when AsyncStreams is initialized in prefix mode.

WriteStream can efficiently handle streams of any sizes. In the receiving side the NewStream event is raised after a complete stream is received.

Note that the data is checked for errors automatically using Adler-32 algorithm. The Error event is raised if the checksums do not match.

While a file is received you can check StreamTotal and StreamReceived properties to track the progress.

The received stream is saved in a temporary file. NewStream event includes the file folder and name. The folder can be changed by setting the StreamFolder field. The file name is an arbitrary string. It is recommended to do whatever needs to be done with the file and then delete it. The files will not be deleted automatically and will not be overwritten.

FileTransfer example demonstrates how AsyncStreams can be used to send and receive files of any size. This example allows you to connect two devices over Bluetooth or Wifi (assuming that both are connected to the same local network).

Once connected you can choose files to send.

SS-2013-06-24_13.24.55.png


The code includes an activity and service. All the communication is managed in the service. The activity is responsible for the UI and it also manages the process of finding unpaired Bluetooth devices.

As mentioned above the progress of received files is monitored with a timer that checks the StreamTotal and StreamReceived properties. In order to monitor the progress of the file being sent we use a CountingInputStream. This is a stream that wraps another stream and counts how many bytes were read.


C# implementation of FileTransfer: http://www.b4x.com/forum/basic4andr...ment-asyncstreams-prefix-mode.html#post178604

Edit: example removed as it was outdated.
 
Last edited:

Mbc

Member
Licensed User
Longtime User
Yes they are.
Some more info:
Communicating using WiFi or BT with other devices on this network but using different apps, runs flawlessly.
Another BT app from Basic4Android (Package=anywheresoftware.b4a.samples.bluetooth) also gives problems. It crashes after a string is sent. After the code:
Sub btnSend_Click
AStream.Write(txtInput.Text.GetBytes("UTF8"))
txtInput.SelectAll
txtInput.RequestFocus
LogMessage("Me", txtInput.Text)
End Sub

anywheresoftware.b4a.samples.bluetooth:
The log when running in Debug does not produce any error.
De app however gives an error text when running in Debug: "Connection broken".
The last four lines in the log:
connected: true
** Activity (main) Pause, UserClosed = false **
** Activity (chatactivity) Create, isFirst = true **
** Activity (chatactivity) Resume **
 

Mbc

Member
Licensed User
Longtime User
The FileTransfer example will only work with two Android devices that run this app.

That makes perfect sense, but how about anywheresoftware.b4a.samples.bluetooth?
The aim of the exercise is to program Android using Basic4Android as to communciactie via BT with the Arduino paltform.
 

GMan

Well-Known Member
Licensed User
Longtime User
The aim of the exercise is to program Android using Basic4Android as to communciactie via BT with the Arduino paltform.
Communication via BT is quite easy, works perfect with several HC-xx devices and several Arduino board types
 

Mbc

Member
Licensed User
Longtime User

GMan

Well-Known Member
Licensed User
Longtime User
but with Serial example
Yes, thats the SPP protocol Erel and I told about.

Finally: Congrats to get it work :)
 

B4A Enthusiast

Member
Licensed User
Longtime User
Hi, am implementing the Asynchronous file transfer code provided in C# in prefix mode. My desktop module is able to send the requested file as shown in the image below:

Asyncstreams Log Screen.png


My problem however is that when the transferred file(s) are saved in the device they are assigned file names that are numeric and without the original file name extensions. How can i ensure that the files saved in the device have the same original filenames as found in the desktop pc? The code for saving is attached here below:

B4X:
Sub AStream_NewStream (Dir As String, FileName As String)
    'this event is raised when a file was received successfully
    Timer1_Tick
    timer1.Enabled = False
'    lblFile = currentFile & " completed"
    ReceivingFile = False
    UpdateProgress
    File.Copy(Dir, FileName, Dir, currentFile)
    File.Delete(Dir, FileName)
End Sub
 
Last edited:

GMan

Well-Known Member
Licensed User
Longtime User
Can't you name the target FileName ?
 

Douglas Farias

Expert
Licensed User
Longtime User
hi @Erel
i have try the example and i have this error

** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (filetranser) Create **
** Service (filetranser) Start **
StartAStream
StartAStream
StartAStream
** Activity (main) Pause, UserClosed = false **
sending message to waiting queue (OnActivityResult)
running waiting messages (1)
java.lang.NullPointerException: name == null
at java.io.File.<init>(File.java:150)
at anywheresoftware.b4a.objects.streams.File.Exists(File.java:91)
at b4a.example.filetransfe.main._cc_result(main.java:751)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:159)
at anywheresoftware.b4a.phone.Phone$ContentChooser$1.ResultArrived(Phone.java:843)
at anywheresoftware.b4a.BA$5.run(BA.java:505)
at anywheresoftware.b4a.BA.setActivityPaused(BA.java:390)
at b4a.example.filetransfe.main$ResumeMessage.run(main.java:271)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException: name == null
** Service (filetranser) Destroy **
** Activity (main) Pause, UserClosed = true **
** Activity (main) Resume **
** Activity (main) Resume **

i dont make changes, only compiled this.
my device is MOTO G
 

tdocs2

Well-Known Member
Licensed User
Longtime User
Thank you indeed, Erel, for a very useful app.

The code for me is beyond my technical expertise since I never had much exposure to network foundations. And as you stated in post 17,
... the code is quite complicated.
However, it is impressive, to say the least. My experience and some questions follow.

Test Environment: 3 Tablets A, B, C running 4.0, 4.3, and 4.4. in the same network
My Testing Results using WiFi ONLY:
1. Connected A to B, B to C. A to C.
2. Transferred files ranging from 1KB to 7MB back and forth.

Findings/Questions
Case 1: A and B Connected. Transfer 7MB File from A to B. Connected C to A - file transfer froze either direction. Shouldn't the File Transfer take priority and deny the new connection?
Case 2: Cannot connect A and B to C at the same time. Can this be done? (Remember my tech limitations.)
Case 3: Is there a way to know which tablet is connected to which tablet. I know Socket.ResolveHost is deprecated.

Any and all help is always welcomed.

Best regards.

Sandy
 
Last edited:

tdocs2

Well-Known Member
Licensed User
Longtime User
Thank you, Erel.

1. Is there a way to know which IP address is connected to the tablet on wifi?
2. A and B Connected. Transfer 7MB File from A to B. Connected C to A - file transfer froze either direction. Shouldn't the File Transfer take priority and deny the new connection?

Any and all help is always welcomed.
Best regards.
Sandy
 
Status
Not open for further replies.
Top