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,299
  • BroadcastReceiver2.0.zip
    5.1 KB · Views: 2,767
Last edited:

viljemto

Member
Licensed User
What would be the difference, if you would have broadcast receiver app made in B4A? In different app, I have in B4A a service with Notification running and it gets killed.

Little broadcast receiver in Eclipse... I have just intent-filter (just like in the link) and it autostart all by itself.

I think it would not get killed, because it is intent-filter and dialer triggers it.
 

viljemto

Member
Licensed User
Hi,

I have tried make a library in Eclipse. Test library works great, but when I want to include lib that uses extends BroadcastReceiver, I get this error.

Maybe has some idea?

2012-12-17_20-35.png

2012-12-17_20-37.png

Thanks, with regards.
 

warwound

Expert
Licensed User
Looks like you need to add the @Hide annotation to one or more public methods in your java class.

I've seen a similar error when a public library method conflicts with the B4A IDE.

Has your OutgoingCallInterceptor implemented an AbortBroadcast method?
If so add @Hide to that method - just before or after the @override annotation.
If you still get problems you might need to add @Hide to other public methods.

Using @Hide prevents that method from being included in the library XML file - if the XML documents a method that already exists within the IDE you get the parse error.
Use @Hide and the error should go away.

Martin.
 

viljemto

Member
Licensed User
Hi,

thank you for helping. You have pointed me in the wright direction.

No, I do not have AbortBroadcast method. I guess it get it from extends.

Unfortunate @Hide did not work. But I have removed AbortBroadcast manually from xml file and then it loaded OK.

But in following code in Eclipse did not work or did not get executed. Got to figure that out. Thanks!
 

viljemto

Member
Licensed User
Hi guys, maybe this information will be useful to somebody.

I have change order of two apps (mentioned before) for intercept outgoing calls and I can say it works great.

1. app in B4A for dynamic BroadcastReceiver for NEW_OUTGOING_CALL: intercept the call and if needed changes to correct number and calls new number.

2. app in Eclipse for canceling the for call/number
if number is changed let the BroadcastReceiver in 2. app cancel the call.

I was surprised how great it works. If somebody is interested, I can upload the code.

With regards, ViljemT
 

walterf25

Expert
Licensed User
Broadcast Receiver

Hello All, i'm trying to intercept an outgoing SMS message, but i get this error everytime!

hope someone here can tell me what i'm doing wrong!


** Service (smsreceived) Create **


BroadcastReceiver has been initialized.
** Service (smsreceived) Start **
BroadcastReceiver has been initialized.


emailname: walterf252000@gmail.com
password: ********
Service sms interceptor started
** Service (smsreceived) Start **


BroadcastReceiver has been initialized.
emailname:


password:
Service sms interceptor started
** Activity (main) Pause, UserClosed = true **
** Service (smsreceived) Start **


BroadcastReceiver has been initialized.


emailname:
password:
Service sms interceptor started
java.lang.Exception: Sub broadcastreceiver_onreceive signature does not match expected signature.


at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:149)
at com.rootsoft.broadcastreceiver.BroadCastReceiver$1.onReceive(BroadCastReceiver.java:110)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:709)
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:3806)
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:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.provider.Telephony.SMS_RECEIVED (has extras) } in com.rootsoft.broadcastreceiver.BroadCastReceiver$1@4056c1a8


at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:722)
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:3806)
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:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: java.lang.Exception: Sub broadcastreceiver_onreceive signature does not match expected signature.
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:191)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:149)
at com.rootsoft.broadcastreceiver.BroadCastReceiver$1.onReceive(BroadCastReceiver.java:110)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:709)
... 9 more
Caused by: java.lang.Exception: Sub broadcastreceiver_onreceive signature does not match expected signature.
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
... 12 more

this is the code

B4X:
Broadcast.Initialize("Broadcastreceiver")
Broadcast.addAction("android.provider.Telephony.NEW_OUTGOING_SMS")
Broadcast.addAction(Broadcast.SMS_RECEIVED)
Broadcast.SetPriority(2147483647)
Broadcast.registerReceiver("")

' Broadcastreceiver sub
Sub Broadcastreceiver_OnReceive (Action As String) 
    ToastMessageShow(Action,False)
   Log(Action)
    'can only abort when sendOrderedbroadcast is called.
    Broadcast.AbortBroadcast
End Sub

the only difference here from the example provided is this line
android.provider.Telephony.NEW_OUTGOING_SMS

other than that i don't see what i get this error./

thanks everyone
Happy Holidays!
 
Last edited:

walterf25

Expert
Licensed User
Broadcast Receiver

Yeah definately there's something wrong with this library, i tried the example that comes with the library and i receive the same error!

java.lang.Exception: Sub broadcastreceiver_onreceive signature does not match expected signature.

hope it can be fixed soon!
 

Shay

Well-Known Member
Licensed User
WOW well done !!!
I will start to test it / use it, cn solve me lot's of issues...
:sign0188:
 

Shay

Well-Known Member
Licensed User
how do I adjust the sample code
to log all the intent that are running in the phone
It seems that I cannot catch anything, so I wish to see everything is running
 

NeoTechni

Well-Known Member
Licensed User
Yeah definately there's something wrong with this library, i tried the example that comes with the library and i receive the same error!



hope it can be fixed soon!

I'm getting the same error, and Broadcast Receiver doesn't show in the list of types when you type sub and press tab


Found it, the new signature is:

Sub BroadcastReceiver_OnReceive (Action As String, i As Object)
Dim i2 As Intent = i
Log(i2.ExtrasToString)
End Sub
 
Last edited:

pappicio

Active Member
Licensed User
hi all.... how to intercept ringermode changed, like this java code:
B4X:
receiver=new BroadcastReceiver(){
        @Override
        public void onReceive(Context context, Intent intent) {
             Log.d("zil", "degisti");

        }
    };
    IntentFilter filter=new IntentFilter(
                    AudioManager.RINGER_MODE_CHANGED_ACTION);
    registerReceiver(receiver,filter);

thanks!
 

RichardBernard

Member
Licensed User
Action_discovery_finished

Hi guys,

I'm trying to get the ACTION_DISCOVERY_FINISHED but it's not working. Can you please tell me what I'm doing wrong?

B4X:
Sub Process_Globals
   Dim Broadcast As BroadCastReceiver
End Sub
Sub Service_Create
   Broadcast.Initialize("BroadcastReceiver")
End Sub

Sub Service_Start(StartingIntent As Intent)
   Broadcast.addAction("android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE ")
    Broadcast.SetPriority(999)
    Broadcast.registerReceiver("")
   ToastMessageShow("DiscoveryService Started...",False)
End Sub

Sub Service_Destroy

End Sub

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

I get my "DiscoveryService Started..." message but no Action is received.

Thanks,
R
 

RichardBernard

Member
Licensed User
Why don't you use BluetoothAdmin object from the Serial library? It already handles this intent.

Do you mean the Admin_DiscoveryFinished event? That only works when search for available devices is done. I'm looking for something that gives an indication after the 300 seconds (or whatever) of being in "discoverable" mode, whether or not a link has been established.

Any ideas?

R
 
Last edited:
Top