Android Tutorial Walkie Talkie - Audio streaming over Wifi or Bluetooth

Status
Not open for further replies.
This example implements a simple "walkie talkie".

270px-Wikipedia_images_011.jpg

(src: wikipedia)

SS-2013-06-30_16.26.21.png


Once the two devices are connected, either over Bluetooth or over the local network, you can press on the activity and talk. The audio captured from the microphone will be sent to the other device and played. Note that this is a half duplex solution, which means that audio will not be received while you send audio. This is to avoid positive feedback (which will also occur if the devices are close to each other).

Most of the code handles the connection. Streaming the audio is done with AudioStreamer object which was introduced in Audio library v1.5.

Note that if you are only interested in audio recording then you should follow the two examples in the above link.

The "interesting" code that is responsible for capturing the audio and sending it is quite simple:
B4X:
Sub AudioStream_RecordBuffer (Data() As Byte)
   If sendingAudio Then
      astream.Write(Data)
   End If
End Sub
Then in the other side:
B4X:
Sub astream_NewData (Buffer() As Byte)
   If sendingAudio = False Then
      'play the received audio data
      audioStream.Write(Buffer)
   End If
End Sub
 

Attachments

  • Walkie-Talkie.zip
    10.7 KB · Views: 10,965

ericvanderhoeven

Member
Licensed User
Longtime User
Here it is =


B4X:
LogCat connected to: B4A-Bridge: unknown MPtouch by imagineear-352272017109967
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
Installing file.
** Activity (main) Pause, UserClosed = false **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
PackageAdded: package:b4a.example.walkietalkie
** Activity (main) Create, isFirst = true **
main_activity_create (java line: 283)
java.lang.NullPointerException
    at anywheresoftware.b4a.objects.Serial.GetPairedDevices(Serial.java:100)
    at b4a.example.walkietalkie.main._activity_create(main.java:283)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at b4a.example.walkietalkie.main.afterFirstLayout(main.java:89)
    at b4a.example.walkietalkie.main.access$100(main.java:16)
    at b4a.example.walkietalkie.main$WaitForLayout.run(main.java:74)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException
** Activity (main) Resume **
main_activity_resume (java line: 322)
java.lang.RuntimeException: Object should first be initialized (EditText).
Did you forget to call Activity.LoadLayout?
    at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:46)
    at anywheresoftware.b4a.objects.TextViewWrapper.setText(TextViewWrapper.java:39)
    at b4a.example.walkietalkie.main._activity_resume(main.java:322)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at b4a.example.walkietalkie.main.afterFirstLayout(main.java:95)
    at b4a.example.walkietalkie.main.access$100(main.java:16)
    at b4a.example.walkietalkie.main$WaitForLayout.run(main.java:74)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: Object should first be initialized (EditText).
Did you forget to call Activity.LoadLayout?
** Service (connector) Create **
main_updateui (java line: 564)
java.lang.NullPointerException
    at anywheresoftware.b4a.objects.Serial$BluetoothAdmin.IsEnabled(Serial.java:394)
    at b4a.example.walkietalkie.main._updateui(main.java:564)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:834)
    at anywheresoftware.b4a.keywords.Common.CallSubNew(Common.java:785)
    at b4a.example.walkietalkie.connector._updateui(connector.java:373)
    at b4a.example.walkietalkie.connector._pe_connectivitychanged(connector.java:204)
    at b4a.example.walkietalkie.connector._service_create(connector.java:315)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at b4a.example.walkietalkie.connector.onCreate(connector.java:42)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2253)
    at android.app.ActivityThread.access$1600(ActivityThread.java:123)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
~e:    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException
main_updateui (java line: 564)
java.lang.NullPointerException
    at anywheresoftware.b4a.objects.Serial$BluetoothAdmin.IsEnabled(Serial.java:394)
    at b4a.example.walkietalkie.main._updateui(main.java:564)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:834)
    at anywheresoftware.b4a.keywords.Common.CallSubNew(Common.java:785)
    at b4a.example.walkietalkie.connector._updateui(connector.java:373)
    at b4a.example.walkietalkie.connector._pe_connectivitychanged(connector.java:204)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at anywheresoftware.b4a.phone.PhoneEvents$ActionHandler.send(PhoneEvents.java:320)
    at anywheresoftware.b4a.phone.PhoneEvents$2.handle(PhoneEvents.java:104)
    at anywheresoftware.b4a.phone.PhoneEvents$16.onReceive(PhoneEvents.java:262)
    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at anywheresoftware.b4a.Msgbox.waitForMessage(Msgbox.java:211)
    at anywheresoftware.b4a.Msgbox.msgbox(Msgbox.java:136)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:206)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:834)
    at anywheresoftware.b4a.keywords.Common.CallSubNew(Common.java:785)
    at b4a.example.walkietalkie.connector._updateui(connector.java:373)
    at b4a.example.walkietalkie.connector._pe_connectivitychanged(connector.java:204)
    at b4a.example.walkietalkie.connector._service_create(connector.java:315)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at b4a.example.walkietalkie.connector.onCreate(connector.java:42)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2253)
    at android.app.ActivityThread.access$1600(ActivityThread.java:123)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException

Looking forward to a few hints. I will give it a try to remove the bluetooth codes

Thanks,

Eric
 

ericvanderhoeven

Member
Licensed User
Longtime User
You should add a Serial.IsInitialized check before the call to Serial.GetPairedDevices.
Hi Erel,

thanks for that. I looked at the code just now (main and connector module) but the bluetooth codes seems to be fully integrated throughout. I have to conclude and accept my novice skill level of all of this. This is above my ''paygrade'' to understand what is what and therefore what is safe to remove or not.

My sole purpose (also with the UDP issue I'm having) is to include a simple method of sending/receiving either 1-to-1 individual (TCP/IP) or broadcast many-to-many (UDP) messages of short length between devices. Streaming audio (the walkie talkie) is the ultimate of that so I gave that a try. In essence, I'd pass short text chats between devices and build from there. The devices I am using are android 4.0.x and have wifi but no bluetooth.

It also should work without a gateway to amply available chat services currently available on the internet. I do not want to use those as they require individual/personal accounts and this should work as simple as possible (personal logins should not be required other than perhaps a first name). I'd also have a fight with system administrators, reluctant to opening up their gateway for this chatter.

In this, I seem to be failing at the lower level already :-(
I could only wish for a sample code that would work on Wifi alone and in that quest, I am currently at your mercy.

Thanks,

Eric
 

Matt Brungs

New Member
Licensed User
Longtime User
Erel,

I downloaded the Walkie Talkie App to my phone and tried to just connect to another bluetooth device. In the message area next to the BT Status I get an Error: java.io.IOException: Service discovery failed. Any ideas on why this is happening
 

AnkitRohilla

New Member
I recently came through this RAD tool and looking at this example, is it really possible that a mere 400 LOC can create a Walkie Talkie in such a sophisticated manner. And the bigger question, are we supposed to be concerned about the code generated by it in the "src" folder. I am a newbie to Android development and wanted to clear these points. Currently, I have installed the trial version and thinking to purchase it within a few days. Please give me some advantages as compared to eclipse.
Thanks to all in advance.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
is it really possible that a mere 400 LOC can create a Walkie Talkie in such a sophisticated manner
Yes. You can try it. It works.

And the bigger question, are we supposed to be concerned about the code generated by it in the "src" folder.
Why should you be concerned about it? Basic4android generates Java code which is then compiler with the Java compiler. You can delete this folder if you like.
 

sorex

Expert
Licensed User
Longtime User
This app works as designed out of the box.

I tried to alter it a bit but the behaviour is not what it should be.

I want to connect to the other phone (phoneB) and press a listen button on phoneA.
When I connect to phoneB and press the listen button on phoneA the sound from phoneA is played on phoneB
instead of the other way around.

What am I missing here?

Do I need to send a command via the socket to make this work the way I want?
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
This is exactly how it supposed to work. You press and talk and the audio is sent to the other device.

If you want to change the behavior then you will need to understand the code and then modify it. You will need to send a message to the other device that tells it to start recording and sending.

You can send a single byte as the message.
 

holzhacker

Member
Licensed User
Longtime User
Dear,

Congratulations on the excellent work ... I would like to know how to identify the PhoneB that the received audio stream was interrupted?

Tanks
 

holzhacker

Member
Licensed User
Longtime User
Thanks for the quick response, but I need to know is when the audio ends being received well, I can take steps to change the images of the buttons on the unit you received and executed this audio (Walkie Talkie), etc.

Sorry forgot to say that I am studying basic4android a little time ...
 

holzhacker

Member
Licensed User
Longtime User
Thanks again for the reply.

The problem is as follows:

PhoneA (send)> PhoneB (receives)

In PhoneA, I can identify the audio stopped being sent by the action of touch, and with that, I can change the image of the "PTT" button to "talk", and change the image again to "talk" to "PTT "when the transmission ends.

In PhoneB can change the image of the "PTT" button to "listening", but I can not pinpoint when the flow ends being received, so I can not change the image of "listening" to "PTT" again, getting image locked in "listening".

Sorry my bad english, I do not practice that much time.

Tanks
 

holzhacker

Member
Licensed User
Longtime User
Again thank you for your attention!

Problem solved.

And I send control messages flow in a SQLite server (Win / Linux) that I developed in PureBasic, but not crossed my mind this solution :( ... sorry

Thanks, I'm still learning about basic4android and congratulations for the excellent support (y) :D
 

figorra

Member
Licensed User
Longtime User
Hi Erel,

I have two devices, one is 4.2.2 Android (PhoneA) and another is 2.3.6 android (PhoneB). When I use PhoneB, I can send, but when I try to receive I have this error..... on PhoneB. The phone A is complete ok......

B4X:
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (connector) Create **
** Service (connector) Start **
Iniciado AsStreaming
java.lang.NullPointerException
    at anywheresoftware.b4a.objects.MediaPlayerWrapper.Play(MediaPlayerWrapper.java:101)
    at b4a.example.walkietalkie.connector._astream_newdata(connector.java:132)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
    at anywheresoftware.b4a.BA$3.run(BA.java:315)
    at android.os.Handler.handleCallback(Handler.java:587)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3691)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: java.lang.NullPointerException
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)
    at anywheresoftware.b4a.BA$3.run(BA.java:315)
    at android.os.Handler.handleCallback(Handler.java:587)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3691)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at anywheresoftware.b4a.objects.MediaPlayerWrapper.Play(MediaPlayerWrapper.java:101)
    at b4a.example.walkietalkie.connector._astream_newdata(connector.java:132)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
    ... 10 more

Is perhaps an Android version problem?

THX
 
Status
Not open for further replies.
Top