We have an android application which we intend to start/launch during phone boot.
With some code tries in Android 10, we realized that the launching of app on boot, is not possible after Android 8.0. Previously in Android 6, it was possible.
Even in physical device /phone / emulator Android 10 , we gave permission in AutoStart list our application.
<< Objective: Any way (workaround) to launch app on boot even on latest versions , i.e. Android 8 onwards ? >>
Tries that we made in Android 10: following are 3 sections of code - AndroidManifest.xml, MyActivity.java, MyBroadcastReceiver.java
1)AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
2)MyActivity.java
public class MainActivity extends FlutterActivity {
#java.lang.Override
protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// "Display pop up window"
if (!Settings.canDrawOverlays(getApplicationContext())) {
startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION));
}
Log.d(TAG, "-------- onCreate -------"); // this is printed
}
}
3)MyBroadcastReceiver.java
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent i = new Intent(context, MainActivity.class);
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(i);
Log.d(TAG, "------ tried to launch MainActivity -------"); // this is printed
}
}
}
Starting the app on boot can be annoying to the user. You can start a Foreground Service instead. The BOOT_COMPLETE intent can be in many different form depending on your device. I have tried to capture all of them here.
In your Manifest:
<receiver android:name=".receiver.BootReceiver" // YOUR RECEIVER HERE
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>
And in the receiver:
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// START FOREGROUND SERVICE HERE
}
}
If your app can get "SYSTEM_ALERT_WINDOW" permission (Draw Over Apps) the app wont get terminated after auto boot on Android 10 onwards.
So you need to display this settings activity and ask the user to enable it:
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 0);
}
This is mentioned in the docs last bullet.
Related
I want to subscribe to the BOOT_COMPLETED intent action, which signals the restart of the mobile phone. Once I subscribe I want to schedule some alarms. I have a BroadcastReceiver that listens to the BOOT_COMPLETED action and it gets hit/called if I use android SDK 25. How can I make the code in BroadcastReceiver execute from Android SDK 26 (Oreo) and above ?
When I run the code on sdk 26 I get the error:
system_process W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.BOOT_COMPLETED flg=0x400010 }
I have created a Github repo https://github.com/Ferencz8/BootIntent on a simpler case, which shows exactly how on sdk 25 things work and on 26 they don't.
Here is the AndroidManifest.xml part:
<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"
android:exported="false">
<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>
</application>
And the BroadcastReceiver:
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
Log.d(BootReceiver.class.getSimpleName(), "In Boot Receiver");
Intent mainActivityIntent = new Intent(context, MainActivity.class);
context.startActivity(mainActivityIntent);
}
}
I have tried in the OnReceive method from the BroadcastReceiver to start a ForegroundService like, but with no luck:
#Override
public void onReceive(final Context context,final Intent intent) {
intent.setClass(context, AlarmBootService.class);
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
}
else{
context.startService(intent);
}
}
I have also tried adding other intent actions besides the BOOT_COMPLETED:
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="android.intent.action.REBOOT"/>
In order to simulate the BOOT_COMPLETED action I used the command:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
Also, this is my first question so if you have any feedback on how to describe/articulate better my question please do tell :).
My implementation of BootBroadcastReceiver
Permission taken in manifest :<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Intent filter in manifest for BootBroadcastReceiver :
<receiver android:name=".receivers.BootBroadcastReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE"/>
</intent-filter>
</receiver>
The additional actions are result of some threads read online.
Below is implementation class :
public class BootBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Application boot event");
Toast.makeText(context, "Boot completed", Toast.LENGTH_SHORT).show();
}
}
But somehow on reboot or power on I am not able to get this boot complete I added the toast also. No toast shown.
Also some people suggested make application install on internal memory only because the boot complete broadcast is not delivered to apps on external storage. By setting flag in manifest android:installLocation="internalOnly" I also did this but not worked for me. What might be wrong ?
Devices used for testing :
Moto E3 power (Android 6.0 ), Lenovo A6020a40 ( Android 5.1.1)
use this code
public class BootBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
Toast.makeText(context, "Boot completed", Toast.LENGTH_SHORT).show();
}
}
}
also define in manifest file receiver like this
<receiver android:name="com.example.startuptest.StartUpBootReceiver" 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>
My application works as a launcher and also it starts on startup. However, something is wrong with it. For instance, I install my application on device, and open it by selecting Always button (as default launcher). There is no problem until here. However, if I reboot my device (it opens on startup, as I said before), the application opens. But when I want to close it, I cannot do that. It opens again.
This is my Manifest file:
<receiver android:enabled="true" android:name=".BootUpReceiver"
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>
<activity
android:name="com.comeks.cocuktablet.Main"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
This is BootUpReceiver.java:
public class BootUpReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
Intent i = new Intent(context, Main.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
You can use the PackageManager to clear your own application of its defaults, put this inside your onCreate():
PackageManager pm = getPackageManager();
pm.clearPackagePreferredActivities("com.your.package.name");
and fill in your own package name. That should clear the launcher default from your app, the next time they press home button they should be shown the choices of which app to use.
I've written following class to start my application activity Home.class but on device start up it shows error forced close.
public class MyBootRecvr extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, Home.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_FROM_BACKGROUND);
context.startActivity(i);
Toast.makeText(context, "Where is my KeyBoard", Toast.LENGTH_LONG)
.show();
}
}
Permissions and receiver tags in application.
<receiver
android:name=".Home"
android:enabled="true"
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>
If this is the only code in your application, it will never run. Android applications must have at least one subclass of Activity as a starting point for when you run the app. The Activity could should at a minimum look something like this:
class MyActivity extends Activity {
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.my_layout); /* my_layout should be an XML layout in res/layout */
}
}
Make sure the following code in is your AndroidManifest.xml file
<activity android:name="MyActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
If you create a new Android project in Eclipse, it will do this setting up for you. There are a lot of tutorials on both setting up a basic application in Android, and using Eclipse to do it for you.
doing this solve the problem
thanks to xono
<receiver
android:name=".MyBootRecvr"
android:enabled="true"
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>
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.