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,914
  • BroadcastReceiver2.0.zip
    5.1 KB · Views: 3,385
Last edited:

canalrun

Well-Known Member
Licensed User
Longtime User
However you can create a static intent filter as described here:
Intent Filters - Intercepting SMS messages in the background

Thanks, that's a very helpful tutorial


Since the new version, i updated the onreceive event with a new parameter. In the onreceive event you should add the parameter:
i as object

Adding the object parameter solves the problem. I can't seem to find documentation for onreceive and this added parameter. What is this object? Does it contain useful information?

Thanks,
Barry.
 
Last edited:

XverhelstX

Well-Known 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
 

canalrun

Well-Known Member
Licensed User
Longtime User
Hello,
Can I ask another question?

In the BroadcastReceiver library, is it possible to use the PutExtra mechanism of Android Intents?

Have the sender add extra information to the Intent and have the receiver read this extra information when it receives the Intent?

With regard to the Intercepting SMS Messages tutorial, I see it uses the extra data within an Intent. Is there a way to receive intents within the Activity (main activity, for example) without having to create a service?

Thanks,
Barry.
 

viljemto

Member
Licensed User
Longtime User
Hi

I am using
B4X:
Broadcast.addAction("android.intent.action.NEW_OUTGOING_CALL")
'Broadcast.SetPriority(2147483647)
Broadcast.SetPriority(999)
Broadcast.registerReceiver("")

In BroadcastReceiver_OnReceive, I get all information OK, but
B4X:
Broadcast.AbortBroadcast
does not cancel Broadcast.

Basically, some times I would like to stop the call from being made. Maybe some idea? Thanks. With regards, Viljem.
 

djpero

Member
Licensed User
Longtime User
Hi

I am using
B4X:
Broadcast.addAction("android.intent.action.NEW_OUTGOING_CALL")
'Broadcast.SetPriority(2147483647)
Broadcast.SetPriority(999)
Broadcast.registerReceiver("")

In BroadcastReceiver_OnReceive, I get all information OK, but
B4X:
Broadcast.AbortBroadcast
does not cancel Broadcast.

Basically, some times I would like to stop the call from being made. Maybe some idea? Thanks. With regards, Viljem.

Try adding permission manually in manifest:
B4X:
AddPermission(android.permission.PROCESS_OUTGOING_CALLS)
AddReceiverText(s1, <intent-filter>
            <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> 
            <category android:name="android.intent.category.DEFAULT" /> 
        </intent-filter>)

and Reflection library:
B4X:
Sub KillCall
    Dim r As Reflector
    r.Target = r.GetContext
    Dim TelephonyManager, TelephonyInterface As Object
    TelephonyManager = r.RunMethod2("getSystemService", "phone", "java.lang.String")
    r.Target = TelephonyManager
    TelephonyInterface = r.RunMethod("getITelephony")
    r.Target = TelephonyInterface
    r.RunMethod("endCall")
End Sub

on Service_Start. This wotking on HTC One X, but having some issues on other phones
 

viljemto

Member
Licensed User
Longtime User
Hi. Thanks.

Why on Service_Start?

It is interesting, that my app receives first and when my code it over, default dialer starts dialing, so I can not kill it, if has not even begun.

I use HTC Desire S. Can you upload sample of project?
 

djpero

Member
Licensed User
Longtime User
Someone familiar in creating libraries for B4A can do that. I need it too, maybe to learn how to do it.
 

viljemto

Member
Licensed User
Longtime User
Yes, I am thinking the same thing. I have tried of doing this in Eclipse, disaster. I went through the samples and How to, but I had errors that I could not resolve.
 

viljemto

Member
Licensed User
Longtime User
Hi

maybe if this information might come useful: to bypass some limitations, I have resolved my problems by doing the following:
  1. create an intent-filter for BroadcastReceiver in Eclipse, not library for B4A, using information published on Android Cookbook: Recipe Process outgoing calls (Recipe 1151, Revision 2810).

    ...so, this catches 1. outgoing phone call and forwards it to intent-filter in B4A.

    Additional information: on Android 2.3.5 HTC Desire S
    setResultData("0123456789"); //does not work
    setResultData(null); //to cancel dialing - works

  • Another intent-filter for processing dialing rules and send it back to first app.

For now...works like a charm :)
 

djpero

Member
Licensed User
Longtime User
Did you export that code to use in b4a or what? I use intent to catch outgoing call but where you using broadcast to set data to null?
 

viljemto

Member
Licensed User
Longtime User
No, I did not export to B4A, I wrote simple app in Ecplise to catch outgoing calls - twice:
1. original number from dialer
2. modified number from b4a
 

djpero

Member
Licensed User
Longtime User
Ahh, I see. You telling that You have two applications, one in Eclipse, one from B4A, which this small one from Eclipse using broadcast receiver and send it to intent of B4A?

If this is true,how you think to install those application in same time from one apk?
 

viljemto

Member
Licensed User
Longtime User
Yes, this is correct - I did not know how to implement this in B4A.

install/update apk - run it twice ;-)
B4X:
Dim Intent1 As Intent
Intent1.Initialize(Intent1.ACTION_VIEW, "file:///sdcard/temp.apk")
Intent1.SetComponent("android/com.android.internal.app.ResolverActivity")
StartActivity(Intent1)
 

djpero

Member
Licensed User
Longtime User
I will try to extend the broadcast library with setResultData function and export it, otherwise I'm not so sure how to combine it with intent of detecting new outgoing call...
 

djpero

Member
Licensed User
Longtime User
Broadcast receiver must be started in service already to do that, intents triggering your service/application and there is the problem how I see the things, because how to set broadcast receiver to listen already started intent to abort it? I think that your little application can be destroyed in processes by some third party service killer, and than you will not be able to start application by dialer.

Maybe this can be resolved with some methods by reflection lib. I have now that working on HTC, but Samsung placing a call and I cannot abort it.
 
Top