B4A Library BroadcastReceiver

Hey,

I'm proud to announce another library of mine: BroadcastReceiver.

I will try to explain as hard as I can, as I didn't went in to deep in broadcasting and stuff.

So, the Android Operating System sends all kind of messages around where the normal users can't see thse. These are called Intents. Every intent has a special role in the Android OS. But the intents don't stay there, wandering around. This is where the BroadcastReceiver comes in. BroadcastReceivers picks up the intents that you need with an intentFilter. This way, you can start actions when something happens in your phone.
But not only can you receive intents, You can also send/broadcast your own intents in your phone, or even pass your own info to another app that it listening.

(please tell me if i'm somewhere wrong ;)) I only learned about broadcasting and intents through this library.

Let me give you an example.

When a SMS text message comes into your phone, the intent "android.provider.Telephony.SMS_RECEIVED" is raised and send "through" your phone. Your standard text application (or even ChompSMS, GoSMS PRO, ...) picks the intent up with a BroadcastReceiver, and displays the incoming message on the notification bar and inbox, etc.

But how does it work now with the BroadcastReceiver Lib?
No manually changing the Android Manifest file is needed!
You only need a service to start working. (and an activity of course to start your service)

In your service process globals, declare the BroadcastReceiver;

B4X:
Dim Broadcast As BroadcastReceiver
I hope you know what this does, otherwise, I recommend you to read Klaus' Beginners Tutorial.

In the service_create, we start by initializing the library.

B4X:
Broadcast.Initialize("BroadcastReceiver")
The parameter "BroadcastReceiver" is needed for calling a sub when an intent arrives. I will explain this later.

After the services has been created and the library has been initialized, we start setting up our receiver that will listen for intents. This is done in Service_start.

B4X:
Sub Sub Service_Start (StartingIntent As Intent)
        Broadcast.addAction("android.provider.Telephony.SMS_RECEIVED")
   Broadcast.addAction(Broadcast.SMS_RECEIVED)
   Broadcast.SetPriority(2147483647)
   Broadcast.registerReceiver("")
End Sub

- AddAction will add the intent you are listening for in a filter. So when a message comes in, "android.provider.Telephony.SMS_RECEIVED" is broadcasted and received.
- SetPriority sets the priority of the listening broadcast. The higher the value, the more important the incoming intent will be thus the quicker it will be called instead of other apps with a lower priority.
- registerReceiver starts your receiver and listening for intents/actions. You can add an extra addAction parameter to the filter.

Now you are done setting up your basic receiver, but now something should be called when a sub arrives: the onreceive method. This is called with the action string of the intent you are listening for.
As I mentionned before, under here starts with BroadcastReceiver, this is the eventname parameter you gave in earlier in the initialize method.

B4X:
Sub BroadcastReceiver_OnReceive (Action As String)
   ToastMessageShow(Action,False)
   'can only abort when sendOrderedbroadcast is called.
   Broadcast.AbortBroadcast
End Sub

The toastmessage, in this case will show android.provider.Telephony.SMS_RECEIVED if an sms has been received.
Next, we stop the broadcast with AbortBroadcast so no other applications will receive this intent. AbortBroadcast will only be called if the broadcast sended is an Ordered one. You can check this with:

B4X:
Broadcast.isOrderedBroadcast

This is basically IT for receiving broadcasts.
Now, there is 1 more thing you should know.

- You can send a broadcast in 2 ways.
1)
B4X:
sendBroadcast(Broadcast.SMS_RECEIVED)

2)
B4X:
sendOrderedBroadcast(Broadcast.SMS_RECEIVED,"android.permission.READ_PHONE_STATE")

Ofcourse instead of Broadcast.SMS_RECEIVED, you can put any string in there that you want.

The difference between these two is that when you send an ordered broadcast, the broadcast will be more accurate filtered on the android permission, and as I said, you can use AbortBroadcast on this one.
You could just open your Android Manifest File and see what permissions your app has.


There are still some more functions, but these are explained in the library itself.

If you want to find info about intents, you can find all of them here:
http://developer.android.com/reference/android/content/Intent.html

Some Intents can't be broadcasted only by the system itself.

In the attachements, you can find the library files and a working sample of BroadcastReceiver.


NOTE: I FORGOT TO CHANGE THE VERSION OF BROADCASTRECEIVER TO 2.0 IN THE IDE. SO THE IDE MIGHT SAY VERSION 1.0 IN THE LIBRARY TAB

Comments, critiques, feedback is welcome!
Have fun!
Tomas
 

Attachments

  • BroadCastReceiver1.0.zip
    285.2 KB · Views: 2,918
  • BroadcastReceiver2.0.zip
    5.1 KB · Views: 3,388
Last edited:

ducphu

Active Member
Licensed User
Longtime User
Hi all,

I use this lib in my app and I see it adds the following permissions:
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_NETWORK_STATE
android.permission.CHANGE_NETWORK_STATE
android.permission.ACCESS_COARSE_UPDATES

I don't see why my app needs these permissions. May I ask if these permissions are important to the lib? Can I delete them w/o affect the lib functions?
 

jarda

Member
Licensed User
Longtime User
You can use it as follow:

B4X:
Sub BroadcastReceiver_OnReceive (Action As String, i As Object)
   Dim i2 As Intent
   i2 = i
End Sub

it will pass the intent back which triggered the broadcastreceiver so you can extract information from the intent.

Regards,
Tomas


Hi

I have one question.
How pass on data to Receiver.

1. Sender

code....

Dim d as Int

'MyData
d = 100

where you enter a value of 100 in Sender

etc ???
Broadcast.sendBroadcast ("myInfo", 'MyData=100')



2. Receiver

code

Sub BroadcastReceiver_OnReceive (Action As String, obj As Object)

Dim inte As Intent
inte = obj

Dim o as Object

o = inte.GetExtra("MyData")

if o = 100 then
ToastMessageShow("Success :)" ,False)
end if

end sub

Thanks for the tutorial
J
 
Last edited:

KL7000F

Member
Licensed User
Longtime User
Hi,
i will usw the Receiver (with BroadCastReceiver) for Airplane_Mode, but i become an error.

My Code:
B4X:
#Region  Service Attributes
    #StartAtBoot: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim Broadcast As BroadCastReceiver
End Sub

Sub Service_Create
    Broadcast.Initialize("BroadcastReceiver")
End Sub

Sub Service_Start (StartingIntent As Intent)
    Broadcast.addAction("android.intent.action.AIRPLANE_MODE")
       Broadcast.SetPriority(2147483647)
       Broadcast.registerReceiver("")
End Sub

Sub BroadcastReceiver_OnReceive (Action As String)
   'ToastMessageShow(Action,False)
End Sub

Sub Service_Destroy

End Sub

This is the Error:
B4X:
BroadcastReceiver has been initialized.

java.lang.Exception: Sub broadcastreceiver_onreceive signature does not match expected signature.
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:189)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at com.rootsoft.broadcastreceiver.BroadCastReceiver$1.onReceive(BroadCastReceiver.java:110)
    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:866)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
~e:    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5300)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.AIRPLANE_MODE flg=0x10 (has extras) } in com.rootsoft.broadcastreceiver.BroadCastReceiver$1@3c0e8bb
    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:876)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5300)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
Caused by: java.lang.RuntimeException: java.lang.Exception: Sub broadcastreceiver_onreceive signature does not match expected signature.
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at com.rootsoft.broadcastreceiver.BroadCastReceiver$1.onReceive(BroadCastReceiver.java:110)
    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:866)
    ... 8 more
Caused by: java.lang.Exception: Sub broadcastreceiver_onreceive signature does not match expected signature.
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:189)
    ... 11 more

Thanks
Andy
 

ArminKH

Well-Known Member
change this sub
B4X:
Sub BroadcastReceiver_OnReceive (Action As String)
   'ToastMessageShow(Action,False)
End Sub
to this one
B4X:
Sub BroadcastReceiver_OnReceive (Action As String,Extra as Object)
   'ToastMessageShow(Action,False)
End Sub
it should work
 

HeX0R

Member
Licensed User
Longtime User
I'm trying to get informed whenever the WIFI state changes, so I tried both, with static and dynamic receivers, but none of them seem to work.

I tried WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION, WifiManager.NETWORK_STATE_CHANGED_ACTION and WifiManager.WIFI_STATE_CHANGED_ACTION but none of them ever get broadcasted.

Any idea what I'm doing wrong?


Here is my service part (dynamic receiver at the moment):
B4X:
#Region  Service Attributes
   #StartAtBoot: True
   
#End Region

Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Dim Broadcast As BroadCastReceiver
   
End Sub

Sub Service_Create
   Broadcast.Initialize("BroadcastReceiver")
End Sub

Sub Service_Start (StartingIntent As Intent)
   Broadcast.addAction("WifiManager.NETWORK_STATE_CHANGED_ACTION")
   Broadcast.addAction("WifiManager.WIFI_STATE_CHANGED_ACTION")
   Broadcast.SetPriority(2147483647)
   Broadcast.registerReceiver("")


End Sub

Sub BroadcastReceiver_OnReceive (Action As String)
   Log("Here I am")

End Sub

Sub Service_Destroy

End Sub
 

JTmartins

Active Member
Licensed User
Longtime User
Hexor, use :
Broadcast.addAction ("android.net.wifi.STATE_CHANGE"), and see how it goes.
 

JTmartins

Active Member
Licensed User
Longtime User
I also take the chance to request instructions if some one now how can we detect a usb flash drive connection in Android 5 ?

I've tryed : Action.MEDIA_MOUNTED ; ACTION_MEDIA_EJECT ; ACTION_MEDIA_REMOVED but none of them seems to work in Android 5

Thanks
 

Krammig

Member
Licensed User
Longtime User
Thanks for sharing this library.
I have just installed the Demo and the V2 library on a phone running 5.1.1 and am seeing the following error ;

B4X:
** Activity (main) Create, isFirst = true **
BroadcastReceiver has been initialized.
** Activity (main) Resume **
Start discovery
Device found: FGT 16810, 88:1B:99:08:F8:52
Discovery stopped
Pairing request: FGT 16810, 88:1B:99:08:F8:52
Not Connected: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
Start discovery
Device found: MPos-000152, B8:32:41:38:6B:85
Discovery stopped
Pairing request: MPos-000152, B8:32:41:38:6B:85
Not Connected: java.io.IOException: read failed, socket might closed or timeout, read ret: -1

Tried two devices as you can see above, same response. I would like to use this, any thoughts ?

thanks
 

Albert Lin

Member
Licensed User
Longtime User
Dear XverhelstX

Thanks very much for this library.
I have 2 question that need your help

B4X:
Sub BR_OnReceive(Action As String, Extras As Object)
     gVibrate.Vibrate (390)                                               
    ToastMessageShow(Action,False)
    
End Sub
Q1: Yes, I can intercept the VOULME_UP or VOLUME_DOWN, but the Action show "android.media.VOLUME_CHANGED_ACTION". How to know which button is pressed? is VOULME_UP or VOLUME_DOWN.

Q2: When the screen off, It seems that BR_OnReceive doesn't happen. How to make BR_OnReceive work while Screen off.

Thanks a lot
Albert Lin
 
Top