I am using AlarmManager in order to set alarm.
I have a Service, and in that Service I have a Broadcast Receiver.
The problem is, when selected time and date comes, receiver cannot receive it.
onStart part of my Service class, and where is register my receiver:
public int onStartCommand(Intent intent, int flags, int startId) {
super.onCreate();
IntentFilter intentFilter = new IntentFilter();
registerReceiver(receiver, intentFilter);
Log.i("com.example.adama", "Service has started!");
return START_STICKY;
}
onReceive Method for receiver:
public static BroadcastReceiver receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i("com.example.adama", "Receiver has received!"); ...}
Part that I run service and set alarm with AlarmManager:
Intent serviceIntent = new Intent(this, BrService.class);
startService(serviceIntent);
Intent intent = new Intent(this, BrService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,alarmCode++, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.adama.wifiv2_spinner">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-feature android:name="android.hardware.wifi" />
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".BrService"/>
</application>
What am I missing?
I am trying this since I want receive it even user closes the app.
If the user force-close your app, there is nothing you can do to make your receiver run, other than the user restarting your app manually.
Other than that, please make sure that you added the BOOT_COMPLETED action to your intent filter, as well as the RECEIVE_BOOT_COMPLETED permission to your manifest, as described in this thread. This will let your receiver start up again after the phone has been rebooted (turned on and off again).
Android BOOT_COMPLETED not received when application is closed
Furthermore, on this thread it has been mentioned that in order for your receiver to work after the app has been closed (not force-closed), the receiver needs to be registered in the manifest:
Is there a way to keep a repeating alarm working after existing the app that uses a broadcast receiver?
Give it a try and let us know if it helped you :)
Related
I'm trying to use a broadcastreceiver to capture a network change but it doesn't seem to be working at all.
My broadcastreceiver:
public class btReceiver extends BroadcastReceiver {
public btReceiver() {
}
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("BB","Received!");
Toast.makeText(context, "Action: " + intent.getAction(), Toast.LENGTH_LONG);
}
}
The way I call it:
IntentFilter filter = new IntentFilter();
filter.addAction(getPackageName() + "android.net.conn.CONNECTIVITY_CHANGE");
btReceiver myReceiver = new btReceiver();
registerReceiver(myReceiver, filter);
But when I try to toggle let's say wifi, nothing happens at all. I also tried declaring it in the manifest like so:
<receiver android:name=".btReceiver" android:enabled="true" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
But that also doesn't work.
I have declared sufficient permissions in my manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
My test device is running Android 7.1.1, does anyone know why it's not firing?
Apps targeting Android N (Nougat) do not receive CONNECTIVITY_ACTION broadcasts, even if they have manifest entries to request notification of these events. Apps that are running can still listen for CONNECTIVITY_CHANGE on their main thread if they request notification with a BroadcastReceiver.
You should register it programmatically or use JobScheduler, GcmNetworkManager or android-job library
Your package name shouldn't be part of the Intent action. So try with:
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
Even better, there's a constant for that:
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
I have read several answers about this question, but the posted solution doesn't work for me. Probably there is something wrong or missed in my code.
I need that my app, with no activity, starts automatically after the boot completed.
If I include an activty, just to start for the first time the app (exiting the stopped state), everything works.
Thank you in advance for your help.
Here is my code.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="zag.salva" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".Salva_autostart"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".Salva_servizio"
android:enabled="true" >
<intent-filter>
<action android:name=".Salva_servizio" />
</intent-filter>
</service>
</application>
Salva_autostart.java
public class Salva_autostart extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Intent intento = new Intent(context, Salva_servizio.class);
intento.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.startService(intento);
}
}
Salva_servizio.java
public class Salva_servizio extends Service
{
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// Task execution
Salva_invio2 invio = new Salva_invio2();
invio.esegui(this);
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
You shouldn’t add FLAG_INCLUDE_STOPPED_PACKAGES to your receiver's intent that start your service. You have to add it to the intent that you use for sendBroadcast. Meaning, you need to add it to the intent in the application that invokes the Broadcast.
That is why this flag is irrelevant in your code.
If you will sendBroadcast to this receiver ("Salva_autostart") just once, from outside your application - then your application will not be in "force stop" state any more and on next boot your receiver will be triggered.
Also you should add (addFlags) and not set (setFlags).
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
This is how you should trigger your receiver from another application:
Intent intent = new Intent("com.xxx.my_filter_intent");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
this.sendBroadcast(intent);
On your manifest add the above filter intent to your receiver (you can add it in new <intent-filter> or in the same that you already have for the BOOT_COMPLETED action.
<receiver
android:name=".Salva_autostart"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="com.xxx.my_filter_intent" />
</intent-filter>
</receiver>
Read more here:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
Note that as of Android 3.0 the user needs to have started the application at least once before your application can receive android.intent.action.BOOT_COMPLETED events.
I'm using a BroadCastReceiver for triggering alarm which is working fine for like 2-3 days, after that it stops working, I am not receiving any alerts in my BroadcastReceiver.
Is there a lifeSpan for Pending Intent?
Actually I'm creating alarms for 30 days. I'm using PendingIntents. Here is the code for PendingIntent:
PendingIntent pendingIntentScheduler = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntentScheduler);
and the receiver at BroadcastReceiver:
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
Log.d("onReceive", "this is broadcast reciever");
}
Android Manifest Permission:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<application>
<receiver android:name=".medicine.modal.AlarmReceiver" android:permission="android.permission.WAKE_LOCK"
android:enabled="true" android:exported="true" android:process=":remote">
<intent-filter>
<action android:name="com.healthsaverz.nimap.healthmobile.healthsaverz.mainscreen.controller.NotificationActivity" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
I found a solution, not legitimate but a bypass. May be this will help someone. What I did is put a repeating Alarm which repeats at every 24 hours, in which I'm recreating all the Pending Intents. Since the life of pending intent is 2-3 days (According to what i found in my app). This results in creating new Pending Intents everyday.
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))
{
//...
}
}
}
I have an app that automatically starts a few seconds delayed after boot. BTW: This is nothing evil! The user must enable it by himself! When I now tap on the app's icon I would like to have the same instance being opened that was already started at boot. I don't want the app to restart. But this is what happens right now.
Background: I'm writing some debug info to a TextView. When the app starts at boot, it is immediately put to background with moveTaskToBack(true), because it should not cover the screen of course. The user should see the IDLE screen. So the app (and in turn this output) can only become visible when the app is opened manually.
Here is the AndroidManifest.xml:
<application android:icon="#drawable/fritzbox"
android:label="#string/app_name"
android:allowTaskReparenting="true"
android:persistent="true">
<uses-library android:name = "com.google.android.maps" />
<receiver android:name=".BootUpReceiver">
<intent-filter>
<action android:name = "android.intent.action.BOOT_COMPLETED" />
<category android:name = "android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity android:name =".WiFiOnDemandActivity"
android:label="#string/app_name"
android:allowTaskReparenting="true"
android:launchMode="singleInstance">
<intent-filter>
<action android:name = "android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
As you can see I've already tried android:launchMode, android:allowTaskReparenting and android:persistent. The broadcast receiver that receives the BOOT_COMPLETED broadcast creates a PendingIntent that is scheduled with the AlarmManager. So the app is started 15s (START_DELAY) after boot. Here is the code:
public class BootUpReceiver extends BroadcastReceiver implements Defines
{
private AlarmManager mAlarmManager = null;
private Intent mIntent = null;
private PendingIntent mPendingIntent = null;
#Override
public void onReceive( final Context context, final Intent intent)
{
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE );
mIntent = new Intent ( context, WiFiOnDemandActivity.class );
mIntent.setAction(intent.getAction());
mIntent.addFlags ( Intent.FLAG_ACTIVITY_NEW_TASK );
mPendingIntent = PendingIntent.getActivity( context, 0, mIntent, 0);
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + START_DELAY, mPendingIntent );
}
}
Strangely enough sometimes it seems to work as expected (no restart) but sometimes it doesn't!
Thanks!
Bernd
Do show your code, but this cannot be guaranteed. The system may kill your process at any time if memory is low, so you might get a new process when you start via the launcher. What makes you think you need the exact same instance?