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

salmander

Active Member
Licensed User
Longtime User
Yes you are. The intent filters are added programmatically but not in the manifest, so when the process is killed, the broadcast listener is destroyed too.

Tomas
Thanks for solving my confusion. Can you please help me regarding, what should I do if I want to make the broadcast listener universal? i.e: a service will be invoked when an OS broadcasts sms_received event, even if the process is killed by OS.
 

salmander

Active Member
Licensed User
Longtime User
No problem mate...I am currently figuring it out. I will post here, it will help others.

Cheers
 

XverhelstX

Well-Known Member
Licensed User
Longtime User

walterf25

Expert
Licensed User
Longtime User
Hello there, i'm trying to create a plug in for an aurpush notification SDK, in the documentation it shows this
B4X:
public class BootReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
new SendDroid(context, “APP_ID”,
context.getPackageName(), true);
}
}
My question is, since i'm really not too familiar with Java, (trying to learn) how can i use your library in this case if possible at all?
so far i have this which initializes the event

B4X:
public void Initialize(final BA ba,  String APP_ID, Boolean testMode) {
         new SendDroid(ba.activity, APP_ID, ba.context.getPackageName(), testMode);
         Log.v("Nick", "PublihserId" + APP_ID);
        Log.v("Nick", "PackageName" + ba.context.getPackageName());
      }

that works fine as i don't see B4A complaint when i run it, but i need to find out how to implement the broadcast receiver on a service module, does anyone here know and can you guys lend me a hand?

thanks in advance everyone,
cheers,
Walter
 

walterf25

Expert
Licensed User
Longtime User
Hi Erel, this is what they have in their Documentation, i just don't understand how to use this, or what this does exactly.

B4X:
<service android:name="com.senddroid.AdService">
<intent-filter>
<action android:name="com.senddroid.AdService<YOUR_APP_PACKAGE_NAME>"/>
</intent-filter>
</service>
<receiver android:name="<YOUR_APP_PACKAGE_NAME>.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME"/>
</intent-filter>
</receiver>

Cheers,
Walter
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You do not need to use this library.
You should add it with the manifest editor with AddApplicationText.

This section can be replaced with a service that is marked with Start at boot option:
B4X:
<receiver android:name="<YOUR_APP_PACKAGE_NAME>.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME"/>
</intent-filter>
</receiver>
 

peacemaker

Expert
Licensed User
Longtime User
Is it possible to detect finish of an app installation and uninstallation ?
If the package name is known.
And result of installation\uninstallation without re-reading all the packages .
 
Last edited:

quimacama

Member
Licensed User
Longtime User
process outgoing calls

Sorry for my english.
I'm developing an app that process outgoing calls. If the contact selected have several phones, replace the mobil phone dialed to the house phone.
I'm using the library BroadcastReceiver and PhoneStateChanged to have control with the outgoing call, but the abortbroadcast does not seem to behave properly, because when the secon call is out, begin the inicial call.
This is my code.
Sub Service_Create
Broadcast.Initialize("BroadcastReceiver")
blnIntercept=True
Log("Service created")
PE.InitializeWithPhoneState("PE",PhoneId)
noti.Initialize
noti.Light = True
noti.Vibrate = False
noti.OnGoingEvent = True
noti.Sound = False
noti.Icon = "icon"
noti.SetInfo( "App", "activated","")
noti.Notify(1)
PhoneFlag = 0
Broadcast.addAction("android.intent.action.NEW_OUTGOING_CALL")
Broadcast.SetPriority(2147483647)
Broadcast.registerReceiver( "") 'here you can add the main action (intent)
End Sub

Sub BroadcastReceiver_OnReceive ( Action As String)
Log("BroadcastReceiver_OnReceive " & Action)
If blnIntercept =True Then
Broadcast.AbortBroadcast
blnIntercept=False
BeginSeconCall
End If
End Sub

Sub PE_PhoneStateChanged (State As String, IncomingNumber As String, Intent As Intent)
Log("PhoneStateChanged, State = " & State & ", IncomingNumber = " & IncomingNumber)
Log(Intent.ExtrasToString)
' ToastMessageShow(State & " " & IncomingNumber,False)
If State = "RINGING" AND IncomingNumber<>"" Then 'incoming call
PhoneFlag = 1
End If
If State = "OFFHOOK" AND IncomingNumber="" AND PhoneFlag = 1 Then 'answering to incoming call
PhoneFlag = 2
End If
If State = "OFFHOOK" AND IncomingNumber="" AND PhoneFlag = 0 Then 'out call
PhoneFlag = 4
End If
If State = "IDLE" AND PhoneFlag = 4 Then 'just out call finished
PhoneFlag = 3
blnIntercept =True
End If
If State = "IDLE" AND PhoneFlag = 1 Then 'just rejected input call
PhoneFlag = 0
End If
Log("PhoneFlag = " & PhoneFlag & ", blnIntercept = " & blnIntercept)
End Sub

I put in the androidmanifest
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
and <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
in then intent-filter

I don't know very much of java, but I want something like this code:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class OutgoingCallInterceptor extends BroadcastReceiver { // 1 @Override public void onReceive(Context context, Intent intent) { // 2 final String oldNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); // 3 this.setResultData("0123456789"); // 4 final String newNumber = this.getResultData(); String msg = "Intercepted outgoing call. Old number " + oldNumber + ", new number " + newNumber; Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); } }

Is possible implement get the oldnumber and replace with the new in B4A with the BroadcastReceiver library?
 

cotralis

Member
Licensed User
Longtime User
is headset plugged in ?

I have a wish.
I want to check if a headset is plugged in.
and take action on this state (an msgbox or som other action).

Erel said it is possible with BroadCastReceiver
he showed this example

See the example here: http://www.b4x.com/forum/addit...html#post70351

The action you should add is: "android.intent.action.HEADSET_PLUG"

But i don't know how to do this.

do you have a working code example?
i want to run this as a service.

thanks
 

JdV

Active Member
Licensed User
Longtime User
Read extra data

Hello

Is extra data contained in a broadcast? (For example the phone number of an incoming call)

Would it be possible to read the phone number of an incoming call using this library? If so, how?

Regards

Joe
 

canalrun

Well-Known Member
Licensed User
Longtime User
Hello,
Thanks for the BroadcastReceiver library.

I have written a little test application, which I have included from File–Export As Zip.

My test app is basically the reverse of the included sample app. I want the service to send a broadcast intent to the main application (if it's running). Eventually I hope to have a service notify the application that an update to data has been made.

When I run this app I get an error on the android device "Sub bcrecv_onreceive signature does not match expected signature." Do you know why I get this error? I would think what I am attempting should be possible, is this true?

I noticed the BroadcastReceiver sample application appears to have been written with B4A 1.7. I am using B4A version 2.02.

Immediately below is the log output, followed by the main and service source code. I have attached the exported project zip file.

Thanks,
Barry.

B4X:
Installing file.
PackageAdded: package:canalrun.apps.bcsender
** Activity (main) Create, isFirst = true **
BroadcastReceiver has been initialized.
** Activity (main) Resume **
** Service (sender) Create **
BroadcastReceiver has been initialized.
** Service (sender) Start **
broadcast sent
java.lang.Exception: Sub bcrecv_onreceive signature does not match expected signature.
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:172)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:154)
   at com.rootsoft.broadcastreceiver.BroadCastReceiver$1.onReceive(BroadCastReceiver.java:110)
   at android.app.ActivityThread$PackageInfo$ReceiverDispatcher$Args.run(ActivityThread.java:892)
   at android.os.Handler.handleCallback(Handler.java:587)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:123)
   at android.app.ActivityThread.main(ActivityThread.java:4627)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:521)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
   at dalvik.system.NativeStart.main(Native Method)
java.lang.Exception: Sub bcrecv_onreceive signature does not match expected signature.

The Main B4A file

B4X:
'Activity module
Sub Process_Globals
End Sub

Sub Globals
  Dim Broadcast As BroadCastReceiver
End Sub

Sub Activity_Create(FirstTime As Boolean)
  Broadcast.Initialize("BCRecv")
  
  'This starts listening for all broadcasts that has the following string: "android.provider.Telephony.SMS_RECEIVED" and sets the priority to the maximum. (this means it will try to first call this receiver)
  Broadcast.addAction("canalrun.apps.sender")
  Broadcast.SetPriority(999)
  Broadcast.registerReceiver("") 'here you can add the main action (intent)

  Activity.AddMenuItem("Start service", "mnuStart")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub mnuStart_Click
  StartService("Sender")
End Sub

Sub BCRecv_OnReceive(Action As String) As String
  ToastMessageShow(Action, False)

  'can only abort when sendOrderedbroadcast is called.
  Broadcast.AbortBroadcast
End Sub

The Sender Service

B4X:
'Service module
Sub Process_Globals
  Dim Broadcast As BroadCastReceiver
End Sub

Sub Service_Create
  Broadcast.Initialize("")
End Sub

Sub Service_Start (StartingIntent As Intent)
  Log("broadcast sent")
  
  Broadcast.sendOrderedBroadcast("canalrun.apps.sender", "android.permission.READ_PHONE_STATE")
  'Broadcast.sendBroadcast("canalrun.apps.sender") ' tried this also
End Sub

Sub Service_Destroy

End Sub
 

Attachments

  • BCTest.zip
    6.2 KB · Views: 262
Last edited:
Top