I'm having an app that must run when android system start-up, I used the usual way of registering the broadcast and receiving it:
in manifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.automation.isolace"
android:versionCode="8"
android:versionName="1.3"
android:installLocation="internalOnly" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
.
.
.
<receiver
android:name="com.automation.standards.BootCompletedReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter android:priority="999">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
.
.
.
</application>
</manifest>
And in BroadcastReceiver class:
public class BootCompletedReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.d("MConn", "BOOT_COMPLETED received");
}
}
then, when the device boots, the app supposed to receive the boot_completed broadcast immediately, but the result varies across different devices, at some devices the app receives it immediately and in others it receives it after a while, this while can be a second or two and at some devices it reaches about 10 seconds, and the problem here is that the app must run before the home screen UI appears, so it has to receive the broadcast immediately.
As appears in the code in manifest, I tried to give the broadcast the most high priority ever, but the issue is still on the table.
So, what are the possibilities that can make this happen, and is there is a way to solve that? and is there is a way to overcome that in a work-around way (like preventing the device from displaying the screen for a while or blocking the system from starting its home activity layout)?
Related
So, I have an alarm application which works good and behaves normally as long as the device remains online until the alarm time.
Problem is, let's say I ran out of battery, or I just want to restart the device... the alarm won't fire upon its time.
I tried something like:
public class BootCompletedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Utils.set_alarms(context);
}
}
}
In my BroadcastReceiver... but doesn't seem to work. Oh, and it's registered in the AndroidManifest too...:
<receiver
android:name=".receivers.AlarmReceiver" // The receiver which starts the alarm activity.
android:enabled="true" />
<receiver
android:name=".receivers.BootCompletedReceiver" // The receiver which is supposed to set the alarms after the device is online again.
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
But doesn't work... help will be appreciated.
You probably need to add the permission to receive boot completed to your manifest. See Manifest Permission: RECEIVE_BOOT_COMPLETED
Add below permission and actions
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name=".receivers.BootCompletedReceiver" // The receiver which is supposed to set the alarms after the device is online again.
android:enabled="true">
<intent-filter>
<!-- used for restart or reboot -->
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<!-- Used for cold boot -->
<action android:name="android.intent.action.BOOT_COMPLETED" />//cold start
</intent-filter>
</receiver>
I'm trying to reset alarms in my app and using a receiver to get onBootCompleted. To see if the intent was received, I'm using a toast. The toast only appears if I immediately open the app. Otherwise, the toast does not appear. I looked at previous questions but almost all of them involve services, which I am not using. I am not sure if that is a part of the problem.
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="internalOnly"
package="package.name" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:configChanges="orientation|screenSize|keyboardHidden"
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop" >
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver" >
<intent-filter>
<action android:name="android.intent.action.ALARM_SERVICE" />
</intent-filter>
</receiver>
<receiver android:name=".AlarmReset"android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
Receiver Class
public class AlarmReset extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Hello! Got message",
Toast.LENGTH_LONG).show();
//reset alarms etc. No service set.
}
I also tried writing the manifest receiver as
<receiver android:name=".AlarmReset" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Key points I found online were to include permissions (which I did) and to watch out for logging.
What I do not understand is why it works if I immediately (within a few seconds, otherwise the toast does not appear) start my activity but is unsuccessful otherwise. I am considering testing a few possibilities like launching the activity itself through code or using a service like most others have. I am currently testing on Android 4.4 on an actual phone.
When an app is installed, it is in a stopped state. None of its components will be activated (such as your BOOT_COMPLETED receiver) until the app is moved out of this state by being launched by the user. This is why your app doesn't work unless you launch it once.
Note that force stopping the app from Settings also moves it into this stopped state.
See this page for more details (search the page for "launch controls").
Starting with Android 3.1 all applications, upon installation, are placed in a "stopped" state.(This is the same state that the application ends up in after the user force-stops the app from the Settings application.)
While in "stopped" state, the application will not run for any reason, except by a manual launch of an activity. (Meaning no BroadcastReceviers(ACTION_PACKAGE_INSTALLED, BOOT_COMPLETED etc.) will be invoked, regardless of the event for which they have registered, until the user runs the app manually.)
But you can start a serivice for ex-
1) In your element:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
2) In your element (be sure to use a fully-qualified [or relative] class name for your BroadcastReceiver):
<receiver android:name="com.example.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
In MyBroadcastReceiver.java:
package com.example;
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}
I feel the need to clarify the issue and solution, since the question was not clear (due to confidentiality issues).
The Basic Solution to my problem was just starting a service.
The Problem: I was trying to make the alarm in my class, AlarmReset, through AlarmManager. That in itself may have been an issue, but in addition, I tried to access objects that were instantiated in the MainActivity, furthering my dilemma. The reason why it worked when I opened MainActivity quickly enough, I suspect, is because I was able to instantiate the objects and set up the prerequisites for the class to directly access. I think the toast not appearing is similar to the issue.
The Solution: I set up a service class which I directed AlarmReset to. This is what I changed the AlarmReset class to:
public class AlarmReset extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Hello! Got message",
Toast.LENGTH_LONG).show();
//Pretty sure the Toast doesn't appear still.
Intent service = new Intent(context, Service.class);
context.startService(service);
}
Then my service class
public class Service extends IntentService {
private DataBaseManager database;
public Service()
{
super("Service");
}
#Override
protected void onHandleIntent(Intent intent)
{
database = new DataBaseManager(this);
Toast.makeText(this, "Hi",
Toast.LENGTH_LONG).show();
Toast.makeText(this, "Hello! Got message",
Toast.LENGTH_LONG).show();
//rest of code
}
Similarly, the text does not appear except if I am on the app immediately (I suspect it has to do with the threads).
Here, I made sure to instantiate my objects before using them (or did so after crashing).
A few possible problems that others may encounter (as I have read) are the following:
Installing in internal storage
android:installLocation="internalOnly"
and receiving permission for booting
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Some problems that people had suggested and were not very important were:
Using android:enabled and android:exported. Default values are fine
Writing the full receiver name. For me it wasn't necessary
<action android:name="android.intent.action.QUICKBOOT_POWERON" /> did not seem to do much.
On boot completed i am starting a service which runs perfectly on emulator but when i run it on android phone Broadcast receiver doesn't start service. Infact app is not even receiving boot completed broadcast from device.
This is my manifest file:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_logo"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name="com.darkrai.smsbasedcontroller.BootReciever"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</application>
This is my broadcast reciever class.
public class BootReciever extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, UpdateService.class));
Log.d("Boot", "Boot Reciever");
}
I was having the same problem and its not your code problem or something.
I was facing this problem because of miui. Miui have the autostart permission disabled for every app.
If you are also using miui device you can do the following option
When you will allow autostart permisson your broadcast receiver will receive the ACTION_BOOT_COMPLETED.
You can allow autostart as
Setting>installed apps>your app> autostart.
Your BroadcastReceiver -- for any action -- will not receive any broadcasts until something on the device uses an explicit Intent to start one of your components. Usually, this comes in the form of the user tapping on an Activity of yours in the launcher.
So, add a LAUNCHER Activity, tap on it, and then you will receive broadcasts until:
the user force-stops you (typically by means of the Settings app), or
the user uninstalls your app
Some devices (mostly HTC) has a feature called fast reboot which doesn't trigger BOOT_COMPLETED. Instead they trigger QUICKBOOT_POWERON.
So add this permission <action android:name="android.intent.action.QUICKBOOT_POWERON" /> also.
i.e.
<receiver
android:name="com.darkrai.smsbasedcontroller.BootReciever"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
I set up a simple app. I wan't to hide it from the drawer and I want to add a Boot Receiver to launch a service.
To hide the application, I read that I had to remove this from the manifest
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
But when I remove it, the boot receiver doesn't work anymore.
I added the permission under the manifest tag
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and my receiver under application
<receiver android:name="com.example.receiver.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
And in the receiver code, there is just a Toast
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot Received", Toast.LENGTH_SHORT).show();
}
}
Why couldn't I set the boot receiver AND the hidden app from drawer?
Thanks
Starting with Android 3.1 all applications, upon installation, are placed in a "stopped" state.(This is the same state that the application ends up in after the user force-stops the app from the Settings application.)
While in "stopped" state, the application will not run for any reason, except by a manual launch of an activity. (Meaning no BroadcastReceviers(ACTION_PACKAGE_INSTALLED, BOOT_COMPLETED etc.) will be invoked, regardless of the event for which they have registered, until the user runs the app manually.)
This is an anti-malware move by Google. Google has advocated that users should launch an activity from the launcher first, before that application can go do much. Preventing BOOT_COMPLETED from being delivered until the activity is launched is a logical consequence of the that argument.
More details about this:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
http://commonsware.com/blog/2011/07/05/boot-completed-regression.html
http://devmaze.wordpress.com/2011/12/05/activating-applications/
I bet it's repeated question but I need to ask it again. Service cannot start even I've put following code
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".MyBroadcastreceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity
android:name="com.im.HomeActivity"
android:clearTaskOnLaunch="true"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.im.ListActivity"
android:label="#string/title_activity_list" >
</activity>
<service
android:name="com.im.SyncService"
android:process=":remote" >
</service>
</application>
and
public class MyBroadcastreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
Intent intent = new Intent(context, SyncService.class);
context.startService(intent);
Log.i("Autostart", "started");
}
}
Help me, please.
Is your BraodcastReciever getting invoked?
if not then the reason could be following:
Starting with 3.1 when applications are installed they are in a
“stopped” state so they will not be able to run until the user
explicitly launches them. Pressing Force Stop will return them to this
state.
once the user runs the app for the first time (and does not Force Stop
it), everything behaves as before — a reboot will cause BOOT_COMPLETED
broadcasts to be received and so on. However, if the user installs the
app, until and unless they run the app manually, no broadcasts will be
received.
So in your case you will have to create launcher activity and make sure you start that launcher activity at least once then you will start receive boot event broadcast.
Source
Starting from Android 3.1, a user must start the application at least once before your application can receive android.intent.action.BOOT_COMPLETED events.
Also android:allowBackup="true" is set in your manifest file, make sure the App is not installed on the SD card. If you are saving to external storage, you will need to setandroid.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE instead.
On some phones(like HTC) there is a Fast Boot option, If it is activated, The BOOT_COMPLETE will not be invoked.
Another approach would be to use Intent.ACTION_SCREEN_ON and check if service is running, if it isn't, then start the service. More info available here