Android receivers being ignored when activity is not active - android

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:

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.

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

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

GCM clarifications

I know these methods are deprecated, but since the new GCM API seems to be buggy, I am reverting to these methods until a stable version is pushed by Google.
We are declaring this receiver inside the manifest.
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.myApp" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
And we have the onMessage() method inside the GCMIntentService class.
#Override
protected void onMessage(Context context, Intent intent)
{
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("msg");
}
1. However, upon receiving a message this method is never called. Why
?
Moreover, the example I follow uses the following.
registerReceiver(mHandleMessageReceiver, new IntentFilter("intent_filter_string"));
associated with the following class.
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String newMessage = intent.getExtras().getString("data");
}
};
which gets unregistered inside the onPause.
Why do we need to create this Broadcast Receiver?
Can't we do this in the manifest ?
Isn't this already covered by the onMessage() inside the GCMIntentService class ?
What role does the Pending Intent String play ?
Answers are appreciated.
Why do we need to create this Broadcast Receiver?
In some cases you might be interested in updating the UI if the app is running.
So you create a broadcast receiver at runtime and unregister it when the app
goes into background.
Can't we do this in the manifest?
Yes, you can do it in manifest too.
Isn't this already covered by the onMessage() inside the GCMIntentService class?
GCMIntentService extends GCMBaseIntentService. So any message coming from gcm,
will first be recieved in the onMessage of the GCMIntentService.
Its upto you to decide how you handle the message.
You can create a notification or send a broadcast to your custom broadcast
receivers and update the UI when the app is running.
What role does the Pending Intent play ?
According to the docs
A PendingIntent itself is simply a reference to a token maintained by the system
describing the original data used to retrieve it. This means that, even if its
owning application's process is killed, the PendingIntent itself will remain
usable from other processes that have been given it.
Did you registered your app/device combination to your GCm project? You have to do that first in the onRegistered Method. And did you add all necessary permissions? Google says you dont have to add the Custom Permissions above android 4.0 but my apps never worked without'em.
If you're looking for an easier way to work with GCM I recommend apiOmat: http://www.apiomat.com I know its Backend as a Service. But if your app is small you don't have to pay anything and it's much easier with it.

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.

how to show call screen while android app running on background

Im making a SIP application for android 2.3.3. I can call someone and my "incoming call screen" is shown when some calls me. But when my app is running on the background and someone calls me , the "call screen" isn't been launched. so how can I make it launch like a normal incoming call.
FIXED:
Manifest: add the following code in application tag
<receiver android:name=".ReceiverTest" android:enabled="true">
<intent-filter>
<action android:name="com.example.INCOMING_CALL" />
</intent-filter>
</receiver>
Receiver class: when I receive a call, it will open my Incomingcall page
public class ReceiverTest extends BroadcastReceiver{
#Override
public void onReceive(Context arg0, Intent arg1) {
...
Intent nextPage= new Intent("com.example.IncomingPage");
nextPage.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
arg0.startActivity(nextPage);
...
}
}
If you are using an Activity your app is not running the background. When a new activity is brought to the top of the stack your application is paused and placed in the background. To allow your application to receive any type of notification try running a service or create a broadcast receiver to pick up the intents you want to listen for. This allows your app to process while it is not on the top of the stack.
UPDATE
So you have registered a broadcast receiver... this is good... but... If you registered it in your activity and the activity is killed, so is the reference and vm of your application and the intent is not received. Try making your broadcast receiver independent of the activity (ie make it be invoked by the system using the manifest). Then your broadcast receiver can receive intents even when your application is dead, and launch what you need.
The alternative is make a service that registers your receiver - a service can run in the background but then you have to worry about making your service light enough to never be killed (more tricks to this). The best best is option 1 (way less overhead).

Categories

Resources