Does BroadcastReceiver can be killed from Android OS to free memory? - android

My app look at arriveed email in K9 client in this way...
1) AndroidManifest:
<receiver
android:name="com.myapp.K9MailReceiver">
<intent-filter>
<action
android:name="com.fsck.k9.intent.action.EMAIL_RECEIVED" />
<data
android:scheme="email" />
</intent-filter>
</receiver>
2) My Broadcast Receiver:
public class K9MailReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
final Intent serviceIntent = new Intent(context, MyService.class);
serviceIntent.putExtra(Prepare.MAIL, intent.getExtras());
context.startService(serviceIntent);
}
}
My question: is it possible that Android decides to kill my K9MailReceiver class to free memory? If yes, how to prevent this?

Any BroadcastReceiver doesn't appear constantly in memory. It get's instantiated when the intent gets received , and killed after onReceive() method is finished.

A receiver only runs when it is being called, so no. Be sure to keep run time under 5 sec though.
However your service may be killed at any time. You can make sure to keep it running by posting an ongoing notification but you probably should not. If it is killed in a low memory situation it will be restarted later.

Related

If a BroadCastReceiver running in a non-default starts a Service, in what process will that Service run?

Trying to get my mind around how processes work in Android.
Let's say that I have a PendingService called FancyService and an Alarm Receiver:
<receiver
android:name=".FancyAlarmReceiver"
android:process=":remote" />
<service
android:name=".FancyService"
android:exported="false" />
Notice that the receiver is process=remote, but the service is not.
Now, let's imagine that the AlarmReceiver just kicks off FancyService...
public class FancyAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MyTestService.class);
i.setAction(intent.getAction());
context.startService(i);
}
}
... then in what process will the service run in? The default process, or the :remote process?
Answering my own question here: The service will run on the default thread, not the remote thread.
I just did an experiment, putting Log.i in the onReceive of the AlarmReceiver, and in the onHandleIntent of the FancyService, and looked in the Android Monitor which process the logs appeared in. The FancyService does indeed log on the main, default process even though it's started by the AlarmReceiver from the :remote thread (and that does indeed log on the remote thread).

How build Android Background Service proper way

I want to build a android background service for check data from MySQL data base.Normally I doing extend from Service class and when start the app,I run service using startService() method.But problem is if i remove the app from task manager,the service is also stopped.Another thing is I want to start this service when start the device,I mean beginning.How I implement this.Help me.
When you kill your app, the service is going to restart, not be removed. You can decrale the flag to define the break point when service restart, and write some 'if' 'else' to do thing after this break point.
And if you want to start serivce when start the device, just create the broadcastReceive call 'autoStart'.
In Manifest:
<receiver android:name=".autoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
and in autoStart class:
public class autoStart extends BroadcastReceiver
{
public void onReceive(Context ctx, Intent arg1)
{
Intent intent = new Intent(ctx,yourservice.class);
ctx.startService(intent);
Log.i("Autostart", "started");
}
}
When started device, system will detect on boot completed, and call this autoStart BroadcastReceive, and call your service from here

Need to shut off a service when a call is coming in and when user dials a number

So, I have a service that runs in the background (it's super secret so I cant tell you what it is:) ) but I need to be able to shut it off when the user initiates a call or a call is coming in. So far, I have checked out the Intent.ACTION_ANSWER, but for some reason, my Broadcast receiver never detects it. I have also tried to use the PhoneStateListener, but in my case statements, I am failing to understand how to do anything with my service. To what context is a PhoneStateListener?
Some example code for my BroadcastReceiver:
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_ANSWER)) {
phoneRinging = true;
}
Intent i = new Intent(context, MyService.class);
i.putExtra("phone", phoneRinging);
context.startService(i);
}
Here is a snippet for starting a service via the PhoneStateListener.
Example: startService(new Intent(---CONTEXT---, MySuperSecretService.class))
And the receiver is in the manifest:
<receiver android:name=".PhoneReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.ANSWER"></action>
</intent-filter>
</receiver>
WTH goes into the CONTEXT portion in this statement if I am in a PhoneStateListener?
Please check ACTION_PHONE_STATE_CHANGED instead of ACTION_ANSWER. ACTION_ANSWER is not broadcast intent for incoming call. It's a standard activity action.

Starting Android Service on boot and PreferenceChange

As my code looks today, I'm periodically sending a alarm(?) using AlarmManager that is received by AlarmReceiver extends BroadcastReceiver which in turn starts a Service. The Service do some updating and ends with a stopSelf(). IMO this is the best way of periodically perfom a task without constantly having a Service running. Correct?
The issue with this code is however that the whole chain of events is initiated onSharedPreferenceChanged(). I (initially) thought this was a good idea since the whole updating thing is enabled by the user in SharedPreferences.
I've now come to the conclusion that this is in fact not very good and that I need to initiate the AlarmManager/AlarmReceiver/Service/whatever both onPreferenceChange but also on boot.
I've done some searching but everyone seems to want to start the Service on boot. As I see it, I just need to initiate the AlarmManager which will then start the Service (when needed and only periodically).
Please help me with, first of all, sorting this out and secondly coding it!
Thanks in advance!
Then, create and register a BroadcastReceiver where you will do the AlarmManager stuff:
public class YourBootReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// do the AlarmManager here
}
}
Then, on your manifest:
<application>
... other stuff
<receiver android:name=".YourBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

BOOT_COMPLETED intents received even though no boot took place

Hey there,
has anyone else discovered that sometimes BOOT_COMPLETED intents arrive out of nowhere?
I have created an OnBootRecoverReceiver which starts a service after it received a BOOT_COMPLETED intent from android - works fine so far... but in some (yet not traceable) events i receive such an intent even though there was no reboot at all.
Anyone has a clue about that, or had the same problem before?
The Manifest entry for the receiver:
<receiver android:name=".trigger.OnBootRecoverReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>`
Receiver Code:
public class OnBootRecoverReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent();
serviceIntent.setAction("de.android.stuff.trigger.OnBootRecoverService");
context.startService(serviceIntent);
}
}
If anyone has a idea, please feel free to help.
To clear things up here: there was no BOOT_COMPLETED intent created anywhere
For some reason the Service (which is startet by the Receiver) crashed on the particular device some time ago. Our good friend the android ActivityManager then decided to re-animate the said Service:
03-16 12:00:02.239: WARN/ActivityManager(2504): Scheduling restart of crashed service de.ukn.hci.android.diary/.trigger.OnBootRecoverService in 5000ms
Which of course led to me thinking the Recevier was fired again, but - as it turns out there was just the Service starting again. Without any REBOOT intent whatsoever.
Solution to stop this:
Add a boolean Extra to the intent created by the Receiver
serviceIntent.putExtra("isFromReceiver", true);
context.startService(serviceIntent);
Then check for this boolean Extra while in onStart(Intent) of the Service
boolean isFromReceiver = intent.getBooleanExtra("isFromReceiver", false);
if( !isFromReceiver ) {
return; //just stop starting the service
}

Categories

Resources