I have a BroadcastReceiver that will run on the background regardless of my application lifecycle. This BroadcastReceiver is initiated on the manifest and launched by a PendingIntent.
I need to stop this BroadcastReceiver at some point, and i must do it inside the BroadcastReceiver it self (inside onReceive perhaps?).
I tried to call abortBroadcast() but no luck, the BroadcastReceiver is still getting called again and again.
Please kindly help me, Thanks a lot for your help
UPDATE
This is how i launch the BroadcastReceiver :
Intent intent = new Intent("mypackage.ACTION_RECEIVE_GEOFENCE");
intent.putExtra("toStation", Constants.toStation);
PendingIntent geofencePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
geofencePendingIntent
).setResultCallback(this);
And this is on my manifest :
<receiver android:name="mypackage.GeofenceUpdateReceiver"
android:exported="false">
<intent-filter >
<action android:name="mypackage.ACTION_RECEIVE_GEOFENCE"/>
</intent-filter>
</receiver>
I use Google's Geofence API
Related
I have a custom button in a sticky notification.
I used to attach a PendingIntent to it for receiving button clicks:
Intent intent = new Intent();
intent.setAction("com.example.app.intent.action.BUTTON_CLICK");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 2000, intent, PendingIntent.FLAG_UPDATE_CURRENT);
contentViewExpanded.setOnClickPendingIntent(R.id.button, pendingIntent);
When i run this code on Oreo , i get BroadcastQueue: Background execution not allowed in logcat and don't receive button click.
I registered receiver with manifest:
<receiver
android:name=".BroadcastReceiver.NotificationActionReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.example.app.intent.action.BUTTON_CLICK"/>
</intent-filter>
</receiver>
I also tried registering receiver in my code:
NotificationActionReceiver mMyBroadcastReceiver = new NotificationActionReceiver();
IntentFilter filter = new IntentFilter("com.example.app.intent.action.BUTTON_CLICK");
mContext.registerReceiver(mMyBroadcastReceiver, filter);
This works but only when the app is visible to user.
Thanks for help
Never use an implicit Intent when an explicit Intent will work.
Replace:
Intent intent = new Intent();
intent.setAction("com.example.app.intent.action.BUTTON_CLICK");
with:
Intent intent = new Intent(this, NotificationActionReceiver.class);
And remove the <intent-filter> from the NotificationActionReceiver <receiver> element.
I ran into this issue as well on Android 8 - Oreo, but given my library project requirements, I don't have the explicitly named BroadcastReceiver class implementation, that the end-client will declare in it's AndroidManifest.
Solution:
Specify the application package on the Intent using setPackage(String).
Example:
// Application unique intent action String
final String receiverAction = getApplicationContext().getPackageName()
+ BaseLibraryReceiver.ACTION_SUFFIX;
// No need for Class definition in the constructor.
Intent intent = new Intent();
// Set the unique action.
intent.setAction(receiverAction);
// Set the application package name on the Intent, so only the application
// will have this Intent broadcasted, thus making it “explicit" and secure.
intent.setPackage(getApplicationContext().getPackageName());
...
From the Android Broadcasts: Security considerations and best practices docs.
In Android 4.0 and higher, you can specify a package with
setPackage(String) when sending a broadcast. The system restricts the
broadcast to the set of apps that match the package.
Here’s an example of the BroadcastReceiver declared (or merged) in to the end-client application’s AndroidManifest:
<receiver
android:name=“com.subclassed.receiver.ReceiverExtendedFromLibrary"
android:exported="false"
android:enabled="true">
<intent-filter>
<action android:name="${applicationId}.action.MY_UNIQUE_ACTION"/>
</intent-filter>
</receiver>
Since my example revolves around a library project that broadcasts an Intent, I’ve decided to keep the <intent-filter> and <action /> in the <receiver> declaration. Otherwise, there would be non-unique broadcast actions being fired, which could lead to potential issues where multiple applications receive the wrong broadcast. This is mostly a safety precaution. Of course you still need to check the action in the implementation of the BroadcastReceiver.
Hope someone finds this helpful!
I have a alarm manager that call a particular service after every 1 minute which do some calculations and send a broadcast to broadcast receiver. I have done this using alarm manager setRepeating().
Here it my code:
Alarm manager:
Intent serviceIntent = new Intent(this, PrayerNotifyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, serviceIntent, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60000, pintent);
It works fine but after rebooting a mobile phone, alarm manager not calling the service.
I have searched on internet and found some solutions like below but they didn't worked for me.
i have also give Boot Complete permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
My Receiver in Manifest:
<receiver
android:name=".NotificationReceiver"
android:enabled="true"
android:exported="true" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</receiver>
Can any one tell me how to solve this issue?
Your broadCast should start service, not alarmManager.
1)Boot device
2)start service from bootReceiver
3)in service start alarmManager.
Hope it helps.
I have an application developed for jelly bean, where I schedule an event to be executed in the future using Alarm manager. The scheduled event executes as expected as long as the application runs in the foreground or in the background. But once I force close the application under taskmanager, I am no longer able to receive the broadcast from the alarm manager.
As suggested by various posts and blogs i tried using Intent.Flag_Include_Stopped_Packages. But it was of no use. Including this flag in the intent works only for sendBroadcast(intent). But in case of an alarm manager where pending intent is used,it does not work.
My code to schedule the alarm
Intent intent = new Intent("com.dummy.intent");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(),dummyId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, scheduledAlarm.getTimeInMillis(), pi);
My mainfest
<receiver android:name="com.example.androidScheduling.alarmReceiver"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.dummy.intent"></action>
</intent-filter>
</receiver>
Can someone please help me out?
I even tried including android:process = ":remote" for the receiver in manifest. But even that did not help.
I think you have not spelled correctly the intent's action name in manifest and programmatically .
In pro-grammatically
Intent intent = new Intent("com.dummy.intent");
Manifest file-
<intent-filter>
<action android:name="com.custom.intent"></action>
</intent-filter>
The action name to intent and declared in manifest must require same.
Hope this helpful to you
I am having a problem with my application's broadcast receiver.
I have a situation where I wan the broadcast receiver to be called for 3 different reasons, first phone state changed, second, based on a timer, and third on boot complete. And then according to the reason by which the broadcast receiver was called I want to be able to do some stuff.
below is my android manifest of my receiver:
<receiver android:name="com.example.mobileraptor.MyPhoneListener" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="com.example.mobileraptor.TimerTriggered" />
</intent-filter>
</receiver>
and the following is where i declare my TimerTriggered intent:
PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("com.example.mobileraptor.TimerTriggered"), 0 );
AlarmManager manager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
manager.setInexactRepeating( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), AlarmManager.INTERVAL_HOUR , pintent );
The problem is that once the application wants to boot it crashes. but if I comment the line :
action android:name="com.example.mobileraptor.TimerTriggered
then my application is fine.
what is wrong with the action name that I have defined.
My question is.
In Android is there a way to create a service which can stay alive even you restart the mobile phone, until it does not perform its task,
For example alarm application. If you restart your mobile it will be triggered without any problem.
In android All services behave like this or do we have some solution for that?
Kindly explain in detail.
It will take 2 steps:
(1) First Create a BroadcastReceiver and start the service in this receiver's onReceive() method:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, YourService.class);
context.startService(service);
}
}
(2) Now decalre this receiver in manifest like this:
<receiver android:name=".MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
This way your Service will always be running and will start even if the phone is restarted. For more details , refer to this link:
http://www.vogella.com/articles/AndroidServices/article.html
is there a way to create a service which can stay alive even you
restart the mobile phone
No. All running services are killed when turning off a phone.
For example alarm application. If you restart your mobile it will be
triggered without any problem.
Yes, but it's not because the service stayed alive. It's because the alarm app respond to the android.intent.action.BOOT_COMPLETED intent.
What you can do is creating a BoradcastReceiver that responds to this intent and that start your service.
The problem is that the user can kill this service manually. If you want to build an alarm clock, you should not have a service always running in the background.
You should make use of the AlarmManager and PendingIntent.
Something like in your manifest :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name=".broadcasts.InitReceiver"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
</receiver>
And something like this for the broadcast.
public class InitReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Schedule your alarms again.
}
}
And you should schedule alarms like this :
Intent intent = new Intent(context, Ring.class);
intent.setData(alarmUri);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, ringTime, pendingIntent );
Where Ring is the broadcast that handles the alarm ring.
In Android is there a way to create a service which can stay alive even you restart the mobile phone, until it does not perform its task,
No, if we interpret your request literally. All processes are terminated when you restart the device, just as all processes are terminated when you turn off the device.
For example alarm application. If you restart your mobile it will be triggered without any problem.
That is because the "alarm application" is getting control at boot time, via an ACTION_BOOT_COMPLETED BroadcastReceiver, and is rescheduling its alarm with AlarmManager.
Similarly, a service implementing a download queue would get control at boot time, via an ACTION_BOOT_COMPLETED BroadcastReceiver, at which time it would determine what yet needs to be downloaded and return to that work.
Check out the Services documentation. You want the START_STICKY flag which will make the system restart your service if it is ever terminated due to low memory etc.
To handle device restart...
Manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<service
android:name=".BootService"
android:label="Boot Service" >
<intent-filter>
<action android:name="com.my.package.BootService" />
</intent-filter>
</service>
<receiver
android:name=".receiver.BootReceiver"
android:enabled="true"
android:exported="true"
android:label="Boot Receiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Source
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(this.getClass().getName(), "Boot Receiver onReceive()");
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction()))
{
// Fire up your service.
Intent serviceIntent = new Intent("com.my.package.BootService");
serviceIntent.putExtra(Constants.BOOT_LAUNCH_EXTRA, true);
context.startService(serviceIntent);
}
}
}
public class BootService extends IntentService {
public BootService()
{
super("BootService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(this.getClass().getName(), "Boot Service onHandleIntent()");
if(intent.hasExtra(Constants.BOOT_LAUNCH_EXTRA))
{
//...
}
}
}