This code will run an app automatically after booting the system, but the app will close after pressing the back button.
If the app is run normally by clicking it's icon. It will continuously run even after pressing the back button or running other apps.
public class AutoBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MyActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
My question is, how to make this auto run code to continuously run even after pressing the back button or running other apps?
You can probably start a Service here if you want your Application to run in Background. This is what Service in Android are used for - running in background and doing longtime operations.
UDPATE
You can use START_STICKY to make your Service running continuously.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleCommand(intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
As apps run in the background anyway, I'm assuming what your really asking is how do you make apps do stuff in the background. The solution below will make your app do stuff in the background after opening the app and after the system has rebooted.
Below, I've added a link to a fully working example (in the form of an Android Studio Project).
This subject seems to be out of the scope of the Android docs, and there doesn't seem to be any one comprehensive doc on this. The information is spread across a few docs.
The following docs tell you indirectly how to do this:
https://developer.android.com/reference/android/app/Service.html
https://developer.android.com/reference/android/content/BroadcastReceiver.html
https://developer.android.com/guide/components/bound-services.html
In the interests of getting your usage requirements correct, the important part of this above doc to read carefully is: #Binder, #Messenger and the components link below:
https://developer.android.com/guide/components/aidl.html
Here is the link to a fully working example (in Android Studio format):
https://developersfound.com/BackgroundServiceDemo.zip
This project will start an Activity which binds to a service; implementing the AIDL.
This project is also useful to re-factor for the purpose of IPC across different apps.
This project is also developed to start automatically when Android restarts (provided the app has been run at least one after installation and app is not installed on SD card).
When this app/project runs after reboot, it dynamically uses a transparent view to make it look like no app has started but the service of the associated app starts cleanly.
This code is written in such a way that it's very easy to tweak to simulate a scheduled service.
This project is developed in accordance to the above docs, and is subsequently a clean solution.
There is, however, a part of this project which is not clean: I have not found a way to start a service on reboot without using an Activity. If anyone reading this post has a clean way to do this, please post a comment.
Starting an Activity is not the right approach for this behavior. Instead have your BroadcastReceiver use an intent to start a Service which can continue to run as long as possible. (See http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle)
See also Persistent service
Related
I'm trying to use Android WorkManager in an application in order to schedule some background task. The requirement is to cancel the API request when the app is removed directly from app-tray.
I'm able to detect if app is getting removed from app-tray, by using Service class -> onTaskRemoved method. And here I'm making the WorkManager API cancel request.
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.d("onTaskRemoved","onTaskRemoved called");
WorkManager.getInstance().cancelAllWork();
}
This is working fine as expected. Please suggest if there is any other better alternative to achieve it.
For some android devices (for some vendors) they implemented like if any apps is removed from app tray means they will force stop the app.So the services,work manager are also stopped.
For some other android devices (for some
other vendors) they implemented like if any apps is removed from app tray means they will stop/kill only the current activity of the app & not force stop the app.So the services,work manager are not stopped.
First you need to check your target devices is comes in which category.
If you need to do this, I think you're probably using the wrong tool. WorkManager is specifically for requests that need to persist and execute at some point. Consider using an Executor or coroutine instead.
Anyone can explain me how keepRunning works in the config.xml for Android.
I mean, I don't want to know how to write the instruction but how does it work, how does it affect the execution of the Android app ? Does it create an Service in background ?
If anyone can find the source where we can see how does it work, that will be great
Thanks.
Edit : I try to analyze the generated code, analyze the RAM, services and processus in the setting of Android. And my conclusion is..... that do nothing.
If you try to make a app which track the user with GPS, dont use Cordova. To track the user correctly, you need to make a Service with the START_STICKY option. So, it's in native code. you lost the interest of the CrossPlatform because you have to recode the service for all platforms and in my opinion, the communication between Native Service and Cordova App is not easy.
In conlusion, if you use Cordova, you have to know you can't use the power of all native, you have to make choise :
- easy dev (subjective) and crossplaform (really crossplatform ?)
and
- Native dev with its power and no compatibility problems but you have to make one app for one platform
I'm not a JS/Cordova developer, I'm an Android developer. Once I worked on a Cordova plugin, faced some issues and did some investigations on the subject.
General purpose of keepRunning flag is to indicate if JS timers should be stopped when the app is paused (goes to background). Answering your question: no, it doesn't create any new Service. Existing design is quite plain in this regard.
The keepRunning flag is defined in CordovaActivity.java as follows:
// Keep app running when pause is received. (default = true)
// If true, then the JavaScript and native code continue to run in the background
// when another application (activity) is started.
protected boolean keepRunning = true;
Its main purpose is to disable JS timers when Cordova app is paused, in CordovaWebView.java:
public void handlePause(boolean keepRunning)
{
LOG.d(TAG, "Handle the pause");
// Send pause event to JavaScript
this.loadUrl("javascript:try{cordova.fireDocumentEvent('pause');}catch(e){console.log('exception firing pause event from native');};");
// Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onPause(keepRunning);
}
// If app doesn't want to run in background
if (!keepRunning) {
// Pause JavaScript timers (including setInterval)
this.pauseTimers();
}
paused = true;
}
Note that plugins are also notified via PluginManager, so in theory they can handle app paused events, to stop (or not) their activity in background, depending on keepRunning flag.
In my case I had an issue/bug when keepRunning was true, but JS timers were stopped anyway. It happened because there is additional functionality related to that flag, in CordovaActivity.java:
/**
* Launch an activity for which you would like a result when it finished. When this activity exits,
* your onActivityResult() method will be called.
*
* #param command The command object
* #param intent The intent to start
* #param requestCode The request code that is passed to callback to identify the activity
*/
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
this.activityResultCallback = command;
this.activityResultKeepRunning = this.keepRunning;
// If multitasking turned on, then disable it for activities that return results
if (command != null) {
this.keepRunning = false;
}
// Start activity
super.startActivityForResult(intent, requestCode);
}
When Cordova app launches another Android activity, main Cordova activity (screen with WebView) goes to background and is therefore paused. In my case it was made via Google Maps plugin which started GM screen over Cordova app.
The code above turns off keepRunning flag, and it means that JS timers are stopped anyway when the called activity appears (in CordovaActivity.onPause method) regardless keepRunning is true or false!
It looks like a kind of trick implemented for some unclear (and not documented) purpose, I do not know its context. In my case it caused a bug, and I just removed keepRunning handling in startActivityForResult, recompiled Cordova and it worked OK.
ADDED: About using a Service for GPS - you are quite right, I agree. As an Android developer with relevant (GPS) experience I can say that a right approach (and possible the only acceptable) is to use a service for that. As far as I know Cordova doesn't provide any functionality for it, so I think it should be made via a plugin. I mean you can write native Android code for GPS functionality (implemented as a Service) and access it from JS code. I believe it is a common solution in Cordova for such cases.
Perfect answer, helped me a lot! I was searching for the solution to the problem for 2 days now.
In my case I'm currently developing a cordova plugin for login purposes. For the login I use an external form which I load in a webview. For two days now I was struggling with the fact that the "Password forgotten" link and every other link on the page I loaded was working, but I wasn't able to submit my form. Only when I hit the back button and through this finished the intent holding the webview, it did submit and proceed.
Turns out that the keepRunning handling was the only problem here. In the end I replaced: `
cordova.startActivityForResult(this, intent, 0);
by:
cordova.setActivityResultCallback(this);
cordova.getActivity().startActivityForResult(intent, 0);
which basically fulfills the whole job Cordova's startActivityForResult would do The only thing that's left out is the whole keepRunninghandling which messed up my plugin in the first place.
Thanks again, Mixaz!
I have developed a mdm server (mobile device manager) and an android application. I have manage to connect the two devices. In addition, I have wrote an android application ,which can work on any android platform. Now, I am trying to manage android application in a way it can not be closed without permission of me.In other words, android application will run from start of the cell phone until I have send a command to close itself.
I do not manage how I can do that. If you know, can you share your knowlege ?
It is impossible to have never ending applications on Android.
Whenever the system requires more resources for the current foreground task, it will kill background processes to free up RAM and CPU.
However, you could do one of the following:
Return START_STICKY or START_REDELIVER_INTENT using a Service
In your onStartCommand() for your service, return START_STICKY or START_REDELIVER_INTENT
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
Use a push notification service like GCM to trigger your app's launch only when needed
This is a much more battery efficient method, as your app isn't running when it isn't required. By integrating GCM, you have the ability to send push notifications to your app via the Google Services already installed on every Google approved Android device (anything with Google Play on it). When the device receives your notification, it will launch and notify your application on the device, hence starting it.
Not possible, you cannot prevent the User killing your application. (Task killers etc)
But what you can do is create a Service and start/stop it via startService/stopService. And make it STICKY.
Android can kill a Service when it is low on resource, STICKY will make the Service start again.
It is a well known saying that "Prevention is better than cure", By These lines I mean You should try and enclose the suspected instruction with try, catch and Finally blocks.
An Application does not close itself until and unless an unexpected flaw or error has occurred. Therefore make sure You've enclosed the sensitive program instruction, such as connecting, looking up for the devices etc. and apply proper instructions in the finaly block. Your program will work according to your demands. Thanks
is it possible to run a broadcast receiver to detect, pause installing and alert when an application is installing.
onRecive
public class Receiver extends BroadcastReciver{
public void onReceive(Context context, Intent intent ){
if(intent.getAction().equals("android.intent.action.PACKAGE_INSTALL")){
//i want to pause the installing activity and prompt an alert box
}
}
}
Purpose would be, when an application is going to install, it ask are you really want to install this application.
After doing a lot of R & D I'm really stuck with a solution for this, if u please can help me out with this, thank you a lot.
This is possible according to this research paper. Look page 2 Figure 1.
You cannot pause it. There is no API for this. This is a system level function not meant to be handled by 3rd party applications.
This is a security measure. Image if every app could control the installation of all other apps! It would be a big security misstep! Hence it's not available.
You can, however detect the installation of a package. See this thread:
Receiving package install and uninstall events
Is it possible to force a reboot of the device after my apk is installed?
I want to force this because I want to ensure that my service is started.
Most probably the answer is no, your are not allowed to do such things from your app. This is the sole privilege of the user holding the phone (and of maybe the core system services).
You can however ensure you service is started when the user starts you main activity, which would be a very normal thing to do right after the user have installed your application.
For additional information see the question How to start android service on installation, which is in fact what you should be trying to do.
It's not possible in any way to get your application to do anything as soon as it's installed, before the user first launches it from the home screen. There's no broadcast action you can listen for explicitly. However, you can listen for something generic that gets called a lot, such as:
android.intent.action.USER_PRESENT,
android.intent.action.SCREEN_OFF, or
android.intent.action.SCREEN_ON
In any case you should NOT reboot the device. Your users will hunt you down and kill you with stones. Joke aside, Google might actually pull your app from the Market for this. Just listen for one of the actions mentioned above, check if the app has just been installed (using a one-time boolean preference, for example) and start the service.
Note: if you do end up listening for one of the above actions, please disable your receiver the first time it receives an intent. You can do this like so (in your receiver):
public class FirstTimeReceiver extends BroadcastReceiver {
public void onReceive (Context context, Intent intent) {
// start your service (which does stuff asynchronously, of course, and then:
final ComponentName mySelf = new ComponentName(context, FirstTimeReceiver.class);
context.getPackageManager().setComponentEnabledSetting(mySelf, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
}
However, you should only do this if somehow this service is absolutely critical for the user (there are few proper scenarios for this), and not for you / your app. As bjarkef mentioned, you should only start it after the user starts your app from the home screen (better yet, ask for permission from the user to run the service).