Android background process - from application start till shutdown - android

I'm developing an app that calculates an algorithm at the background. Since the application starts, till it ends.
This is a tracking algorithm (with now further explanation about the algorithm operation principles).
So the background task need to be calculated at all screens on the app regardless of user actions on app, clicks, wifi communication messages (already done on app) , everything needs to be done while the algorithm is running at the background.
Is it an AsyncTask ?
If not what else?
The application is running and the algorithm is being calculated at a specific screen now, i want to make it a background process with no respect to current application screen.
An example will be appreciated
P.S- Further developing , do not need to be discussed if not needed right now:
1. The next stage is to insert an indication (virtual bulb) that change between to states depends on algorithm result each time.
2. The algorithm is getting data from USB device attached to the phone as the phone is the host using FTDI chip.

It's clearly a Service that you need - that's exactly their main purpose - to do long-running operations in the background, no matter what Activity the user is playing with in the foreground. You can read more about Services HERE.

Use broadcast reveicer
You need to define a receiver in manifest with action name android.intent.action.BOOT_COMPLETED.
<!-- Start the Service if applicable on boot -->
<receiver android:name="com.prac.test.ServiceStarter">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
Make sure also to include the completed boot permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Use Service for this to make anything persist. And use receivers to receive Boot Up events to restart the service again if system boots..
Code for Starting Service on boot up. Make Service do your work of checking sms or whatever you want. You need to do your work in MyPersistingService define it your self.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class ServiceStarter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent("com.prac.test.MyPersistingService");
i.setClass(context, MyPersistingService.class);
context.startService(i);
}
}

It's clear that you need execute your algorithm in a independient thread. You must choose how you want do this.
My recommendation is a Service or a IntentService.
https://developer.android.com/training/run-background-service/index.html
You can get a fantastic example here, with a Service which is running in the background and a TimerTask executed each a period of time.
App to monitor other apps on android

Related

What to use instead of android.app.action.ENTER_CAR_MODE in API 26

Starting with Oreo, Android forbidden use of implicit broadcast receivers in Manifest and adviced to register receiver at runtime and or use JobSchedule instead. There is a list of some exceptions as well, however I cannot find an acceptable answer to my situation.
I have a service which runs in the background only when the phone is in CAR mode, up till now I use this to determine when the device entered/exited the car mode and started/stopped the service accordingly:
<intent-filter>
<action android:name="android.app.action.ENTER_CAR_MODE"/>
<action android:name="android.app.action.EXIT_CAR_MODE" />
</intent-filter>
I had a look in the JobSchedule builder but I cannot find anything which relates to CAR, only to charging, network type, and other irrelevant stuff for my case.
How I'm supposed to tackle this?
Any ideas please?
Based on your needs
A service which starts when the device goes into car mode and ends when he leaves it without having the user watching at your application (so without opened activities)
is probably the type of things Google wanted to avoid with the new API 26 restrictions to prevent battery drains. Entering and exiting the car mode should produce only a change of the UI if the user is watching your app while doing this.
You could create a JobScheduler and run it at X minutes interval to check for the actual device condition with UiModeManager#getCurrentModeType() and start a foreground service if the condition is met, but this is a lot far from your current behaviour and the user will be notified of this by a fixed notification.

Android application as a service without activity

I am making a set of apps and I have pretty much the same background service for all of them.
I'm trying to make an app that has only this Service. so I don't repeat it in all of them, but the thing is don't need any Activity. because there is no UI needed for it, and so the user can't close it except if they stop the Service.
I tried to remove the Activity, but then the app doesn't run or start.
My question is: can I make an app exactly like Google Play Services so other apps can use its Service.
If yes than a snippet or a sample would be very welcome.
Sure! No reason you cannot have an application with only a service. ...and no need to get into AIDL unless you want to.
The problem is, how to make the application run. When you create an application with an Activity, you add an Intent filter, in the manifest, that makes the activity startable from the Launcher. If there's no activity, you'll have to find another way to start it.
It is easy to do, though. Just fire an intent from one of your other programs, like this:
startService(new Intent("my.service.intent"));
... where the service is registered your manifest, like this:
<service android:name=".SomeService" >
<intent-filter>
<action android:name="my.service.intent"/>
</intent-filter>
You could use that intent to pass Parcelable parameters to the service, and the service can reply by broadcasting intents back.
Of course startService and broadcastIntent are a bit clunky if you really need a complex API between applications and your service. If you need something richer, you will want to look into AIDL and a Bound Service.
Edited to add Intent Filter

Is there a way to detect when the user has changed the clock time on their device?

Is there a way to detect when the Android system clock has been reset by the user in Android?
I'm designing an app which uses system time to determine when a user is at a certain place at a certain time, and I don't want to rely on network availability at that point. Obviously it would therefore be good to know when the user has changed the system clock, so they can't "cheat".
Yes, there is. The ACTION_TIME_CHANGED Intent is broadcast when the device time is changed, and you can have a method which will trigger when this Intent is detected.
This intent has been in Android since API level 1, so it should work on any platform you might need to be compatible with.
You'll need to handle the Broadcast with a BroadcastReceiver:
public class TimeChangedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Do whatever you need to
}
}
You'll also need to add something like this to your Manifest:
<receiver android:name=".TimeChangedReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
</receiver>
This will let Android know to trigger your receiver when this type of intent is detected.
It appears as though this doesn't care who edits the time, but also does not trigger on automatic adjustments when you are synced with the network. If you lose network and regain it, though, this will likely fire since your time will be slightly different (assuming you are using automatic network time).
However, while the clocks on cell phones are not particularly accurate (since they generally rely on syncing with time signals they receive) in my experience they absolutely should not lose more than about 30 seconds or a minute per hour, at the absolute maximum, so if the time change is small you can perhaps assume it was automatic. Leap seconds, when they are added, will also likely produce a time change message, although these are obviously small and infrequent.
You can use ConnectivityManager to keep track of whether the phone has a connection or not and you can change the behavior based on that (i.e. as long as network connectivity is there, and the time is automatic/network time, ignore time changes or something) but I can't find any intents regarding losing/regaining network connectivity so you will probably have to use a polling method.
The system time (System.currentTimeMillis()) would change if the user adjusted the clock, but the elapsed time since boot (SystemClock.elapsedRealtime()) hopefully would not. By tracking the differential between these two, it would be possible to detect major changes to the system clock by the user.
It would be important not to track small changes that might be caused by the network updating the system clock. I'm going to assume that for my purposes, any change under about a half hour is irrelevant; the system time shouldn't change on the Locale country changing but that might be worth eliminating also.
The elapsed realtime would obviously reset on boot so I should include a BroadcastReceiver to reset the differential on receiving android.intent.action.BOOT_COMPLETED.
A little notice to the answer of matt5784: I found out that on Android 4.1.2 the intent action is not available, donĀ“t know if this is for all android versions or just at mine. Instead of
"android.intent.action.ACTION_TIME_CHANGED"
use
"android.intent.action.TIME_SET"
We can use both TIME_SET and TIMEZONE_CHANGED.
<application
...>
<receiver android:name=".TimeChangedReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
</intent-filter>
</receiver>
</application>
TimeChangedReceiver.java
public class TimeChangedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "time change " + intent.getAction(), Toast.LENGTH_SHORT).show();
}
}
If you don't mind your app to throw cheats in case of user's clock will get updated due to *DT/*ST shifts, occasional time syncs with NTP sources that can rewind your clock, your own process's stalling, you can implement a "consequential" check on system time so that if time went "back" you assume it's a "cheat". Otherwise, you have to rely on the server which will be your source of "valid" time. And even then, your server's time can too go backwards occasionally.

Reboot after install

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).

Can code be called when my Android application is uninstalled?

Does anyone know if a specific method is available to be overridden when my application is uninstalled? It would be nice to remove these users from the server side database when this occurs.
Unfortunately there is currently no way for an Android package to execute code when it is removed. However, you can register a BroadcastReceiver for ACTION_PACKAGE_REMOVED in a different package that will be called when packages are removed from the phone.
Also see this question.
I know I'm late to the party, but I'm guessing that since for you uninstalling the app is sufficient to blow away the user at the server (as opposed to the user explicitly picking a "delete my account" option), I would create a job on the server/service-side that scans for inactive users every N units of time (eg. 30 days) and deletes them. Why? An app that never connects to your server is as good as an app that is uninstalled.
However, you can then build logic in your app to handle the case when those users that never uninstalled the app, but don't log in for over N units of time, eventually come back. Then, you could:
make the app send a special "I'm already installed" cookie to the server, which then instructs the app to send it enough app-side cached info to reconstruct the user data at the server while saying "Please wait, syncing with server...". This should work as long as the user data is not huge (for eg. some sort of image library), and if it is, your best bet then is to indicate in BOLD letters that inactive accounts will be deleted.
Or, of course, you could also just reset the app to its original state and hope the user does not hate you.
You could go the route to install a service as part of your app that wakes up once a day and when WiFi is available and the device is on A/C power, sends a "heartbeat" to your service saying "I'm installed". If the heartbeat stops for more than a few days, you can assume the user uninstalled the app and delete the user data. But note that this is not foolproof, since the user may simply have turned the device off for that many days. In which case, you now have to handle the situation when a heartbeat comes in for a user that is no longer active in the system, at which point you will need to build in reconstruction logic as before (which buys you nothing for having gone through this pain of building the heartbeat, thanks a lot), or, you simply reset the app to its fresh state and hope the user doesn't hate you (which again buys you nothing for having gone through this pain of building the heartbeat, thanks a lot).
Those pesky users! ;-)
Yes, there is a way where you can Use Android listener application to install and uninstall App.
App install and uninstall will send a broadcast when the application installation is complete, the system will listen android.intent.action.PACKAGE_ADDED broadcast. The name of the package that was installed by intent.getDataString(). When the uninstall program system listens android.intent.action.PACKAGE_REMOVED the radio. The same intent.getDataString() to get the the uninstall package name. The application can not monitor the installation and uninstallation, but cover the installation can listen to their own android.intent.action.PACKAGE_REMOVED broadcast.
Example
AndroidManifest.xml configuration file:
<receiver android:name="com.sarbjot.MyApp.BootReceiver" >
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
And the receiver call:
package com.sarbjot.MyApp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// install call
if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
//code here on install
Log.i("Installed:", intent.getDataString());
}
// uninstall call
if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {
//code here on uninstall
Log.i("Uninstalled:", intent.getDataString());
}
}
}
I hope it will help you all.
Yes, You can handle it by identifying click on Uninstall Button from Settings -> Manage Apps -> Selects a particular application.
try this answer.
Hopefully this will works.

Categories

Resources