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.
Related
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 am trying to launch my application when I turn my android device on. Currently I have a BroadcastReciever class and a Service class however the app does not seem to launch when I reboot my device.
My BroadCast Receiver Class
public class Bootup extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
Toast.makeText(context, "Reboot completed! Starting your app!!!.", Toast.LENGTH_LONG).show();
Intent i = new Intent(context, AutoStart.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(i);
}
}
}
My Service class
public class AutoStart extends Service {
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:sharedUserId="android.uid.system">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<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" >
<receiver
android:name=".Bootup"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name=".AutoStart">
<intent-filter>
<action android:name="com.example.test.AutoStart"></action>
</intent-filter>
</service>
<activity
android:name=".MyActivity"
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=".Result"
android:label="#string/title_activity_result"
android:parentActivityName=".MyActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.test.MyActivity" />
</activity>
<service
android:name=".functionality"
android:enabled="true" />
</application>
</manifest>
Could someone point me in the right direction. I am not sure what I am doing wrong.
Your application needs to be manually run at least once before boot receiver start working, also boot intent might be send after quite some time and maybe even intercepted and killed by other apps. I encountered such behaviour with few third party sms apps.
I'm not entirely sure about this, but try removing the android:exported="false" from the BootBroadcastReceiver. android:exported="false" means no other app can call it, and the system is just as an app in here.
Try using context.startActivity(i); instead of context.startService(i);.
You should correct this line in your BroadCast Receiver Class:
Use: context.startActivity(i);
Instead of: context.startService(i);
I'm trying to start my service at bootup, but I keep getting the 1245-1263/? I/ActivityManager﹕ Waited long enough for: ServiceRecord{3d8aa3b0 u9 myPackage/.myService} exception.
I've looked at this: My service always getting Waited long enough for: ServiceRecord error in Kitkat
which told me that the ActivityManager is putting starting my service on hold. I've confirmed through log statements that my receiver is indeed working. Here is the code in case anyone is interested:
public class PhoneStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("OnStartUp", "Service is about to be started");
Intent myIntent = new Intent(context, myService.class);
context.startService(myIntent);
}
}
So, how can I set my service's priority to "essential" so that Android makes sure it starts? I looked at this: How to set the priority of android service? but it deals with restarting a service rather than the initial startup.
Here's the relevant bit of my manifest:
<receiver android:name=".PhoneStateReceiver"
android:enabled="true"
android:label="PhoneStateReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service
android:name=".myService"
android:enabled="true"
android:exported="true" >
</service>
Thanks in advance.
You have to register a bootup-completed broadcast receiver and from there start your service. Here is a working implementation. Perhaps its the <uses-permission> part you're missing?
EDIT
In my manifest (important parts) I have that <uses-permission> part at the beginning.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<!-- for services (must be rescheduled after boot) -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".services.BootCompletedReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</manifest>
My receiver class looks like this. Note, I'm starting an IntentService.
public class BootCompletedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent msgIntent = new Intent(context, ReminderService.class);
msgIntent.setAction(ReminderService.ACTION_RESCHEDULE);
context.startService(msgIntent);
}
}
From the code that is posted, it looks like the manifest is looking for a service called .myService and in the BroadcastREceiver you're trying to start a service called LocationService.class.
This could be the issue.
I have a service in my Android app that works perfectly if i started manually, but i need that service to start on boot, and i can't get it started automatically after rebooting the phone, i tryed several tutorials but nothing works.
Here is my manifest code:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tvshowsguide"
android:versionCode="1"
android:versionName="1.0"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
<service android:name="androidservice.SyncService" />
<receiver android:name="androidservice.SyncAuto" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Here is the BroadcastReceiver code:
public class SyncAuto extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Intent SyncService = new Intent(context, SyncService.class).setAction(SRVC);
context.startService(SyncService);
}
}
}
I think the problem must be the reference of your service, since you have an application with
package="com.tvshowsguide"
Your service and receiver must have a name like:
<service android:name="com.tvshowsguide.androidservice.SyncService" />
<receiver android:name="com.tvshowsguide.androidservice.SyncAuto" >
I want to start my application automatically when the phone boots.
I declared a BroadcastReceiver in the manifest file.
<receiver android:name=".Autostart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
I made a java file for the receiver.
Autostart.java
public class Autostart extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, MushTouchActivity.class);
pushIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(pushIntent);
}
}
}
But, the application does not launch when I switch my phone on. Can anyone tell me what I am missing here ?
try your if statement like this:
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
Intent i = new Intent(context, MushTouchActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
In case you are on Android 3.1 or newer:
Make sure that you started your application at least once manually (e.g. by opening it from the app drawer). Otherwise your app is marked as stopped by the system:
Applications are in a stopped state when they are first installed but are not yet launched
Stopped apps do not receive any broadcast intents, including BOOT_COMPLETED.
See Android 3.1. Platform - Launch controls on stopped applications for more information.
The best answer would be to show a Notification and ask the user to launch the app from that notification and use a pending intent for that activity in the notification.
Tested on Android 10
1. Create A Broadcast Listener
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == "android.intent.action.ACTION_SHUTDOWN") {
// Your tasks for shut down
} else {
// Your tasks for Boot up
}
}
}
2. Config Manifest
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<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:theme="#style/AppTheme">
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.REBOOT" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
</intent-filter>
</receiver>
</application>
If you search for a sample application code for working with services in background and control actions on screen off/on then visit this repo:
https://github.com/varunon9/DynamicWallpaper
you can update this repo source code with step 1 and 2 for control boot and shutdown events in addition to screen on/off.