Restore Alarm manager after phone reboot - android

i am building a small widget for learning purpose, it simply has an configuration activity where i set the update interval. it works normally and i can create multiple instance of it.
but when i reboot the phone the alarm manager stops, and the widget won't update.
after some search and google'ng i learned that i have to add a BOOT COMPLETE receiver
but after several attempts i failed to implement so any one has an i idea about how to add that or any good source code example on widgets.

To do something at boot you simply do following.
First in the manifest, this is added under application tag:
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="packagename.ACTION"/>
<action android:name="packagename.ACTION2"/>
</intent-filter>
</receiver>
<receiver android:name="BootSetter" >
<intent-filter>
<action
android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
In order for this to work you need to add permission to receive the Broadcast in the manifest with following line:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Then you have a class BootSetter:
public class BootSetter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Do your stuff
}
}
There is a similar post, though not completly the same here. It's about running an alarm every day at noon.

I think you are setting alarm manager in class other then AppWidgetProvider extended class(widget class) .Better you should set an alarmmanager in OnUpdate method AppWidgetProvider extended class (widget class)then there will be no need of setting the alarm again after boot.

Related

Android job scheduler not persisted on reboot

I have implemented Job scheduler in my project and it works fine in the case if the app is in background or if the app is killed. But it is not working if the device is rebooted. I have included
JobInfo.Builder mBuilder = new JobInfo.Builder(TASK_ID, mComponentName);
mBuilder.setPersisted(true);
in my builder and
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
in application manifest file.This is how I have added my service to manifest
<service
android:name="com.xxx.xxxx.service.MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
Is there anything else to be included?
Thanks in advance
Register a BroadCastReciever for detecting BOOT_COMPLETED.
<receiver android:name="com.example.startuptest.StartUpBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
And in your BroadcastReceiver:
public class StartUpBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
...
}
}
}
Once a user runs any activity in your app once, you will receive the BOOT_COMPLETED broadcast after all future boots.
I know it is an old question, and you probably already have the solution, but the issue likely was, that JobService caches the UUIDs of the apps that have the permission. You will need to reinstall your app and it is gonna be alright.
Source:
https://android.googlesource.com/platform/frameworks/base/+/5d34605/services/core/java/com/android/server/job/JobSchedulerService.java
You need to call the setPersisted(boolean isPersisted) method.
You can find it in the doc https://developer.android.com/reference/android/app/job/JobInfo.Builder.html#setPersisted(boolean)

How do I use the intent action USER_PRESENT?

I have a clock widget application, and I need to recognize when the phone has been unlocked or not, I believe I can use action USER_PRESENT for that, but I can't get it to launch in the BroadcastReceiver class, I set it in the manifest like this:
<receiver
android:name="com.myApp.myApp.MyWidgetIntentReceiver"
android:exported="false"
android:label="widgetBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" >
</action>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/demo_widget_provider" />
</receiver>
And this is how I trying to get it in the BroadcastReceiver:
public class MyWidgetIntentReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_USER_PRESENT){
Log.i("TICK", intent.getAction());
}
}
}
It's not firing after I unlock the phone, can you help me out or provide me a better way to check when the phone has been unlocked? thanks!
Remove android:exported="false"
android:exported:
Whether or not the broadcast receiver can receive messages from sources outside its application — "true" if it can, and "false" if not. If "false", the only messages the broadcast receiver can receive are those sent by components of the same application or applications with the same user ID.
Source : developer.android.com
Remove android:exported="false". That worked for me on Stock Android 5
I got it to work by using registerReceiver in the onUpdate method of the AppWidgetProvider class and passing an instance of the BroadcastReceiver class to register the Intent.ACTION_USER_PRESENT, since adding it only in the Manifest was not doing anything. Thank you!

Boot receiver doesn't work

I'm trying to implement a broadcast receiver that catch the boot complete event.
I put the permission in the manifet
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
I put the intent filter after the receiver tag in the manifest (the class file is in the receivers package)
<receiver android:name=".receivers.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.REBOOT" />
</intent-filter>
</receiver>
and finally I declared the receiver class. The class should load some data from the database and set an alarm. However to check if it works I've put a Toast but it's not displayed and a vibra.
public class BootReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent callingIntent) {
Vibrator vibrator=(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(5000);
Toast.makeText(context, "BOOT RECEIVED", Toast.LENGTH_LONG).show();
}
}
Anyone knows why please?
All just installed applications gets into the stopped state (the actual file is /data/system/packages-stopped.xml)
Starting from Android 3.1, the system's package manager keeps track of applications that are in a stopped state. See this link: android 3.1 launch control.
Intent with action android.intent.action.BOOT_COMPLETED has a FLAG_EXCLUDE_STOPPED_PACKAGES extra flag. It means that all stopped applications will not receive the BOOT_COMPLETED events.
To get your application out of the stopped state, start it manually just after installation. Then you can do a reboot and will see the expected Toast.

Widget onUpdate called when Configuration Activity is launched

I'm implementing a widget and I'm facing the following problems:
1) onUpdate is called when I add the widget to the home screen, even if I specified a Configuration Activity. As soon as I add it to the home screen, the APPWIDGET_ENABLED broadcast is sent, followed by the APPWIDGET_UPDATE and then the configuration activity is launched.. Is this a bug? How should I understand in the onUpdate method that is being invoked before the configuration activity has returned? I can do it through a shared preference value, but I'd like it to behave as written on the developer guide, i.e. the onUpdate method should not be called.
2) onUpdate is not called every updatePeriodMillis seconds, which have been set to 10000, i.e. 10 seconds for testing purposes.. Did I miss something in the receiver declaration within the Manifest file? I keep receiving the Lint warning Exported receiver does not require permission but I think this is a Lint issue and not my fault.
EDIT: I've just found this within the reference docs: Note: Updates requested with updatePeriodMillis will not be delivered more than once every 30 minutes. So it is correct that the widget is not updated how often I'd specified and I've changed the time to 1800000 milliseconds.
3) I want to deliver my own broadcast action to the widget provider, is it correct to add another receiver block in the Manifest targeting the same provider class or should I add only another intent action within the intent-filter that contains the APPWIDGET_UPDATE action? BTW, I've commented my second receiver block and it is not the cause of the problems above. I created another receiver block because I wanted to declare it as not exported, in order to let the intent-filter action be triggered only by my app code and not anyone else.
AndroidManifest.xml
<receiver android:name="MyWidgetProvider"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/my_widget_info" />
</receiver>
<receiver android:name="MyWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="org.test.mywidget.FORCE_SMALL_WIDGET_UPDATE" />
</intent-filter>
</receiver>
my_widget_info.xml
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp"
android:minHeight="110dp"
android:updatePeriodMillis="1800000"
android:initialLayout="#layout/my_widget_layout"
android:configure="org.test.mywidget.MyWidgetConfiguration"
android:resizeMode="none">
</appwidget-provider>
Providing an answer after digging into the source code:
1) This is expected behavior see here
This method is also called when the user adds the App Widget
2) Seems you have found your own answer. For others looking for the docs go here
Note: Updates requested with updatePeriodMillis will not be delivered more than once every 30 minutes
3) Since the AppWidgetProvider extends BroadcastReceiver but is not declared final you can add the action from your second receiver
<receiver android:name="MyWidgetProvider"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="org.test.mywidget.FORCE_SMALL_WIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/my_widget_info" />
</receiver>
then you can override onReceive in your MyWidgetProvider class and if the action is your custom action handle it, otherwise call to the super.onRecieve(Context context, Intent intent) like so:
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction()
.equals("org.test.mywidget.FORCE_SMALL_WIDGET_UPDATE")){
// handle your action
} else {
super.onRecieve(context, intent);
}
}
as per the Guide:
AppWidgetProvider is just a convenience class. If you would like to
receive the App Widget broadcasts directly, you can implement your own
BroadcastReceiver or override the onReceive(Context, Intent) callback.
One thing to note with this, the update to the remote view will only be called at the updatePeriodMillis, regardless of you adding your own action to the Intent for the provider to handle.
Good Luck and Happy Coding!

Start Alarm on Android without having the application running

My idea is to set an alarm for a specific date in my application, but I want to be able to have the alarm ringing at the set date, even if my application isn't running at all.
How can I achieve this?
Thanks in advance!
I'd start a service when the device is booted - that service should take care about the alarming when the time has come.
To make your service be started at boot time you need the following things in your AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
in the <manifest> tag
<receiver android:name="com.yourpackage.AlarmingBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
in your <application> tag
Additionally you need your AlarmingBroadcastReceiver, should look something like that to start the service:
public class AlarmingBroadcastreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, AlarmingService.class);
context.startService(startServiceIntent);
}
}
whereas AlarmingService.class is the class name of your service that finally takes care about the alarming stuff
You will need to create a onBoot BroadCast Receiver so when the device is started your application will get control to set up alarms.

Categories

Resources