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>
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've implemented a BroadcastReceiver according to https://developer.android.com/guide/components/broadcasts but it does not seem to work.
The receiver part of my Manifest.xml looks like this (I use android.permission.ACCESS_NETWORK_STATE and android.permission.ACCESS_WIFI_STATE):
...
<receiver android:name=".BackgroundTask">
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
...
and it's declared within my application.
My BroadcastReceiver class looks like this:
public class BackgroundTask extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("Connection changed!");
Toast.makeText(context, "Network state changed", Toast.LENGTH_LONG).show();
}
}
Neither the toast is displayed nor I receive the println-ed output on my logcat.
I also read the note which recommends me to use scheduled jobs instead of receivers, but I could not find an example how to use this for listening to network changes.
The reason I want to use this is because I want my (background)-app only to run while my phone is connected to my WiFi - if you have any different suggestions on how to implement this, I'm also very thankful.
Btw. I'm using Android 8.0.0.
Cheers,
Nikolar
Update:
Somehow it still does not work. Am I forgetting anything?
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mypackagename">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<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>
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
<receiver android:name=".BackgroundPoller">
</receiver>
</application>
</manifest>
Just for clearence I renamed my BackgroundTask-Class to BootReceiver:
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("INFO", "BootReceiver started");
Intent newIntent = new Intent(context, BackgroundPoller.class);
context.sendBroadcast(newIntent);
Log.d("INFO", "BackgroundPoller activated");
}
}
When I successfully send my broadcast
adb.exe shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED
I still don't get a log output.
To get around Oreo's broadcast receiver restrictions, you have to register your receivers using Context.registerReceiver(). You could do this by subclassing Application and registering receivers in onCreate(). The only downside to doing this is your app would have to be launched to have Application.onCreate() get called. To get around this, you could register an ACTION_BOOT_COMPLETED receiver in your manifest as this action is exempt from the restriction. Your ACTION_BOOT_COMPLETED receiver doesn't have to do anything, but it will force your app to start running on boot and therefore Application.onCreate() will get called. Then the only challenge is keeping your app running because the system will kill it if the user doesn't go into it. There's a couple options to solve this. You could write a foreground service whose only purpose is to keep the app alive. Or perhaps use AlarmManager to schedule some intent that will wake your app back up, which will register your receivers again.
I have a service that I would like to start on BOOT COMPLETE
when it is started , I have a toast message displayed.
my problem is that when the device boots up , the toast is displayed and is stuck on screen, and the service is not starting correctly.
however if I am trying to start my service through an activity , the service is starting well and the toast disappears after a few seconds correctly.
my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tfl.extprotocolservice"
android:versionCode="7"
android:versionName="1.6" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<application
android:allowBackup="true"
android:icon="#drawable/launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="com.tfl.extprotocolservice.ExtProtocolBroadcastReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".ExtProtocolService" >
<intent-filter>
<action android:name="com.tfl.extprotocolservice.ISetIpPort" />
</intent-filter>
<intent-filter>
<action android:name="com.tfl.extprotocolservice.IExtMessage" />
</intent-filter>
</service>
<!--
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
-->
</application>
</manifest>
my broadcast receiver:
public class ExtProtocolBroadcastReceiver extends BroadcastReceiver {
/* broadcast receiver to start on BOOT COMPLETE*/
#Override
public void onReceive(Context context, Intent intent) {
Intent StartServiceIntent=new Intent(context,ExtProtocolService.class);
context.startService(StartServiceIntent);
}
}
btw, the activity in the manifest is commented because I don't really need it , it was just to test starting the service from an activity.
If your application has no activities, your BroadcastReceiver will never get called.
When you install an application, it is installed in the "stopped state". applications in "stopped state" do not get broadcast Intents delivered to them.
In order to get your application out of "stopped state", the user must manually launch your application (at least once). In order to do this, you must offer him an Activity that he can use to start your application.
Once your application is no longer in "stopped state", Android will deliver broadcast Intents to it. That is, until the user "force stops" your application.
If the user "force stops" your application, it will go back to "stopped state" and will no longer get the broadcast Intents. Until the user manually starts your application again.
I tried with am broadcast -a android.intent.action.BOOT_COMPLETED then it restart the device.
You can try <action android:name="android.intent.action.USER_PRESENT"/>
After more research, I think it was the fastboot mode which will not broadcast BOOT_COMPLETE.
Your service is filtering actions, but your intent doesn't provide any.
Fix with this:
StartServiceIntent.setAction("com.tfl.extprotocolservice.IExtMessage");
I have registered a BroadcastReceiver called CheckReceiver:-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.captchachecker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:icon="#drawable/ic_launcher"
android:installLocation="internalOnly"
android:label="#string/app_name"
>
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".CheckReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
</application>
</manifest>
CheckReceiver code:-
public class CheckReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Check Receiver", "Captcha Receiver called");
Toast.makeText(context, "Receiver called", Toast.LENGTH_SHORT).show();
Intent service = new Intent(context, CheckService.class);
startWakefulService(context, service);
}
}
The problem is that when I press the power button and choose Power off option, BroadcastReceiver is not being called.
If I restart the device using:-
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
then BroadcastReceiver is being called.
I have read about launching activity atleast once for BroadcastReceiver and launch an activity 2-3 times before checking.
Turns out I had used:-
adb shell pm set-install-location 2
in the past on my device. The app got installed to sd card ignoring:-
android:installLocation="internalOnly"
After I moved the app to phone it started working properly. To move the app to phone go to:-
Settings->Apps->Your app and choose "Move to Phone"
So, if your boot receiver doesn't works. Check:-
Permissions and intent filter in the manifest are declared properly.
App has atleast one activity and it has been launched atleast once by user after installing or after the app is force closed.
App has been installed to internal storage.
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