Android - How to trigger a Broadcast Receiver to call its onReceive() method? - android

I have scheduled alarm for my application.
I have implemented broadcast receiver to be triggered once the alarm time reaches.
How to manually call broadcast receiver to execute the code inside of onReceive method without replicating the code twice.
I thought of having the code in utility singleton call and call that method by having util class instance from anywhere.
But is that any other way to call that onReceive method directly or else broadcast intent problematically.
android:exported="false" //Additional parameter of receiver when
defining in manifest file.
Another question is what is that exported parameter means. Please help me to understand this.

1. The way to launch a BroadcastReceiver manually is by calling
Intent intent = new Intent("com.myapp.mycustomaction");
sendBroadcast(intent);
where "com.myapp.mycustomaction" is the action specified for your BroadcastReceiver in the manifest. This can be called from an Activity or a Service.
2. It is known that Android allows applications to use components of other applications. In this way, Activitys, Services, BroadcastReceivers and ContentProviders of my application can be started by external applications, provided that the attribute android:exported = true is set in the manifest. If it is set to android:exported = false, then this component cannot be started by an external application. See here.

Here is a more type-safe solution:
AndroidManifest.xml:
<receiver android:name=".CustomBroadcastReceiver" />
CustomBroadcastReceiver.java
public class CustomBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// do work
}
}
*.java
Intent i = new Intent(context, CustomBroadcastReceiver.class);
context.sendBroadcast(i);

You need to mention the action which is required to be filter by Android OS to notify you.
i.e.:
inside manifest file,
<receiver
android:name="com.example.MyReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="com.example.alarm.notifier" />//this should be unique string as action
</intent-filter>
and
whenever you want to call broadcast receiver's onReceive method,
Intent intent = new Intent();
intent.setAction("com.example.alarm.notifier");
sendBroadcast(intent);

How to manually call broadcast receiver to execute the code inside of
onReceive method without replicating the code twice.
Fire BroadcastReceiver using sendBroadcast same action which added in AndroidManifest.xml :
Intent intent=new Intent(CUSTOM_ACTION_STRING);
// Add data in Intent using intent.putExtra if any required to pass
sendBroadcast(intent);
what is that android:exported parameter means
As in android:exported doc : Whether or not the broadcast receiver can receive messages from sources outside its application — "true" if it can, and "false" if not
Means if:
android:exported=true: other application also able to fire this broadcast receiver using action
android:exported=false: other application not able to fire this broadcast receiver using action

Related

My Android broadcast receiver is never triggered

In AndroidManifest.xml I have this:
<receiver android:name=".MyBroadcast" android:exported="true"/>
My broadcast file:
package com.myapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, Radio.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
}
}
I am trying to run application after close it to play music in background.
That's because you never specify what intent you're actually listening for.
You need to register the broadcast receiver to listen for specific broadcasts (events), either in the manifest using the intent-filter tag or dynamically at runtime. See this question for more discussion about the difference.
Here's an example of how to do this in the manifest (from the linked question):
<receiver android:name="TestReceiver">
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY"/>
</intent-filter>
</receiver>
This means that the broadcast receiver is listening for the AUDIO_BECOMING_NOISY intent. (You'll want to replace this with a more appropriate intent that reflects when you want this to run).
There's a very useful list of Intents that you can listen for here. You can select a broadcast from there (or from one of the libraries) or, if you're listening for an event that occurs within your application, you can raise the broadcast yourself.
Also, make sure that the event in question is actually being raised. If the broadcast you're listening for never happens, the broadcast receiver will never actually be triggered.
For related reading, see the Observer Pattern (which is the design pattern that Android Broadcast Receivers implement).
onReceive() method is only called when the event you have registered for occurs. You have not declared that event that will trigger the onReceive() method. So, the Broadcast Receiver doesn't know what it should listen for.
You should read more about the Broadcast Receivers and Activity Lifecycle methods from Android Docs.
I don't think you need to use Broadcast Receivers. You can use Activity lifecycle methods to do whatever you want when your application closes.
onReceive() method is only called when the event you have registered for occurs. You have not declared that event that will trigger the onReceive() method. So, the Broadcast Receiver doesn't know what it should listen for.
You should read more about the Broadcast Receivers and Activity Lifecycle methods from Android Docs.
This is similar to asking person X(anyone) to get ________ from the market for you. He is in the market looking for ________ but he does not know what it is. So, obviously, he can't get it for you. You need to tell the receiver what to look for.

Send broadcast from one apk/package to another apk/package

I need to send broadcast from my one application to another applicaion.. any help!
my application package are 1)com.demo.database and 2)com.demo.list
Intent themesIntent = new Intent(ThemesManager.THEMES_UPDATED);
themesIntent.putExtra("package", packageName);
ctx.sendBroadcast(themesIntent);
not working..
Edits :
<receiver android:name="com.sample.ThemesUpdatedReceiver">
<intent-filter>
<action android:name="com.sample.THEMES_UPDATED"/>
</intent-filter>
</receiver>
#Ajit: Hi, Since Android API 3.0 [API level 11], If an application has never been started even once, then it's BroadcastReceiver can't receive events.As, in your case, your app has no launcher activity, so may be it is the case that causes rejection of event.
Along with that please try using below approach:
You have passed that constant value while creating Intent object. Instead pass it in method intent.setAction();
Hope this helps.
I figured that every sent broadcast is received by all applications except when you setPackage to the sending intent for specific package broadcast.
I am not receiving broadcast because my another app is not launched(that doesn't have launcher activity).
If you're going to broadcast, it generally follows you have a sender and receiver. You've posted what looks like the sender ..
sender (where ever you're sending from):
Intent toret = new Intent();
toret.setAction("com.myapp.foo");
toret.putExtra("bar", "fizzbuzz");
sendBroadcast(toret);
receiver (in eg onResume())
IntentFilter intentFilter = new IntentFilter("com.myapp.foo");
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// ... do something with the intent
}
// register the receiver
this.registerReceiver(receiver , intentFilter);
Sender always sends, receiver needs to register to listen for the intent.

Cannot receive android.intent.action.MEDIA_MOUNTED when BroadcastReceiver is registered dynamically

I am trying to register a BroadcastReceiver programmatically to receive android.intent.action.MEDIA_MOUNTED. However, the onReceive() method never gets triggered. The same BroadcastReceiver class I created works fine if I register is statically in the app's manifest file.
Why is this the case? Is there a way to troubleshoot this? I need to register dynamically because my BroadcastReceiver class contains members that I want a service to query later on. If I catch this Intent statically then I have no easy way of querying these members because I believe the instance of BroadcastReceiver gets deleted as soon as onReceive() finishes. Is this correct? I am pretty sure this is the case considering the Android documentation has the following to say about this:
If this BroadcastReceiver was launched through a tag, then the object is no longer alive after returning from this function.
UPDATE 1:
Here is my dynamic registration code:
if (externalStorageListener == null)
{
Log.d(TAG, "creating externalStorageListener...");
IntentFilter filterExternalStorage = new IntentFilter();
filterExternalStorage.addAction(Intent.ACTION_MEDIA_MOUNTED);
filterExternalStorage.addDataScheme("file");
filterExternalStorage.setPriority(Integer.MAX_VALUE);
externalStorageListener = new ExternalStorageBroadcastReceiver();
registerReceiver(externalStorageListener, filterExternalStorage);
}
Here is the intent filter in my manifest that actually works:
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<data android:scheme="file"/>
</intent-filter>
Occasionally, to receive android.intent.action.MEDIA_MOUNTED with dynamically created BroadcastReceiver one is to have android.permission.MOUNT_UNMOUNT_FILESYSTEMS defined in manifest:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
android.intent.action.MEDIA_MOUNTED action can be handled by privileged system application only. That action can not be received by 3rd party applications
May be when you create receiver dynamically your intent filter is different compared to when it is created through the <receiver/> tag? Could you show us both your manifest part and the code part?
Also, instead of storing data in receiver's fields, you could consider other options:
A content provider
Shared preferences
A singleton object
In that case there will be no difference between statically and dynamically created receivers.
EDIT: Based on the provided code, the problem is probably in priority setting:
Applications must use a value that is larger than SYSTEM_LOW_PRIORITY and smaller than SYSTEM_HIGH_PRIORITY .
SYSTEM_HIGH_PRIORITY = 1000

Broadcast receiver works only when device reboot android

Hi I am developing android application in which I am defining one broadcast receiver.I am calling receiver from my activity. I am defining broadcast receiver like this :
public class MyScheduleReceiver extends BroadcastReceiver {
private static final long REPEAT_TIME = 100 * 5;
#Override
public void onReceive(Context context, Intent intent) {
Log.i("RRRRRRRRRRRRRRRRRRRRRRRR", "on receive");
}
}
In android manifest file I am defining like this:
<receiver android:name="abc.xyz.MyScheduleReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
and in main activity I am calling my broadcast receiver like this :
//in activity oncreate
startService(new Intent(this, MyScheduleReceiver.class));
My problem is that when call start service it's not starting my service actually. But when i restart my device it start my service because I gave intent filter "BOOT_COMPLETED". what I wanted to do actually when i call start service my service must be start,
Am I doing something wrong. How to solve this problem?
Actual what happens here is that you can staring a broadcast receiver while starting the activity and this broadcast receiver starts listening BOOT_COMPLEATED is happening or not. When this happens it comes to onreceive . If you need to start a process doing in background you can use a a Service insted of BroadcastReciever. BroadcastRecievers are used to listen for some events to happen.Go through this, it will help you
Services
BroadcastReceiver
You're either confused, or you aren't wording your question well. What you have in your manifest (and how Android works generally) is that when BOOT_COMPLETED occurs, it will call that BroadcastReceiver you defined. It will not automatically start an activity or service. If you want to do that, you need to call startService or startActivity in your onReceive function of the receiver.
You do not start BroadcastReceivers. You start services, which are long term background processes. You register BroadcastReceivers to be informed of special events (like BOOT_COMPLETED). When one of the events you registered for occurs, it will create an instance of that class and call its onReceive.
Hopefully that clears things up. If not, I suggest you reread some tutorials on services and broadcast receivers, you seem to have the two confused.
startService call would only start a Service. MyScheduleReceiver here is a braodcast receiver. To trigger broadcast receivers, you generally have to send broadcasts and not call the startService.
to start broadcasts you need to send broadcasts not startService()
add this instead of startService(new Intent(this, MyScheduleReceiver.class));
Intent intent = new Intent();
intent.setAction("pakagename.MyScheduleReceiver");
sendBroadcast(intent);
I hope it helps.

Android receivers being ignored when activity is not active

I have a background service which has a receiver for connectivity change which only seems to be received if the activity is active.
#Override
public void onCreate() {
mContext = this;
IntentFilter connectivityChangeFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(receiver, connectivityChangeFilter);
I've set it up in the manifest as follows:
<service
android:name="com.myservice.TimeService"
android:label="com.myservice.TimeService" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</service>
I have another receiver for boot completed which works ok, which is registered as a receiver in the manifest (unlike this one).
Is the intent filter not enough to run a broadcast? I would want the receiver to call a method on the service so it needs to be able to access methods of the service but I don't think receivers can bind to services.
-- Update
In a nutshell, I want to know if I can statically declare a receiver that interacts with a service. Dynamic declaration works only if the app is active.
Use android sticky intent
A normal broadcast Intent is not available anymore after is was send and processed by the system. If you use the sendStickyBroadcast(Intent) method, the Intent is sticky, meaning the Intent you are sending stays around after the broadcast is complete.
example code here:

Categories

Resources