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
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.
I've made a foreground service to constantly scan for BLE devices around me. For some reason it seems to work flawlessly on my stock android device Google pixel and also on Samsung S9+.
But recently I tested the app with a Chinese ROM(Oneplus 6T, Xiaomi Poco F1) the foreground service seems to be killed there after a few minutes. I've used workmanager to restart service but the app is not restarting and I get a bug report instead for the app.
Also on Chinese ROM devices below android 8.0(Xiaomi redmi 3s prime), simple service wont work, I need to use a foreground service there as well. Is there any solution to solving this?
Ask users to whitelist your app. This is the only solution. Even foreground service + wake lock won't work.
There was a discussion last month: Workmanager reliability for periodic tasks on Chinese roms (Xiaomi, Huawei, and so on). There are some useful links in there but eventually you'll have to let users whitelist your app in every ROM's specific battery optimization(or other name) settings.
A simple approach would be to ask user to put your app in non-optimized apps by opening the battery optimization settings at the starting of your app
Use below code to open the setting:
Intent batterySaverIntent=new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS);
startActivity(batterySaverIntent);
Or you can try this:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
startForegroundService(new Intent(this, ServiceClass.class));
}
My app main usage is overlay, the overlay is running from a service.
Android Security add the nice "Screen Overlay Detected"
I want to avoid "Screen Overlay Detected" when user tries to change permissions. so... I've add an AccessiblityService that detects:
if ( event.getPackageName().equals("com.google.android.packageinstaller") ){
stopService(myServiceIntent);
}
However, even now I see this message popping. (when my service is stopped...).
I saw Twilight does it without problem.
What am I missing?
p.s. - I've also tried building a signed apk but saw exact same behavior.
It seems I've been able to resolve this.
a) stopService isn't assured your service will be stopped.
as described here :
It will not be destroyed until all of these bindings are removed. See > the Service documentation for more details on a service's lifecycle.
b) I was able to kill my service by sending intent that called stopSelf().
However process killing/starting can be slow.
c) Best resolution: so it seems Android checks for view visibility. no need to kill services or do anything more complicated.
Current way I'm doing it:
- AccessibilityService (already used by my app) monitor "com.google.android.packageinstaller" though it can be refined to class: "com.android.packageinstaller.permission.ui.ManagePermissionsActivity"
Once detected in this class, we send Intent to "duck", and when we're out, we send another intent that we're back on.
The service handles those calls by:
[ourView].setVisibility(View.INVISIBLE); // when permission settings shown
[ourView].setVisibility(View.VISIBLE); // when normal flow
As long as Android 6.x is buggy on some devices where this "overlay alert" is displayed without any reason (on 2 to 5% of the devices according to my analytics data), the best solution is to avoid the whole permission process by defining the targetSdk to 22. Take care that you can't downgrade the target sdk for a new version or this will induce a INSTALL_FAILED_PERMISSION_DOWNGRADE error when the user updates requiring an unisntall/install of the app.
I am working on android multi-user. So I have to convert my existing project in to multi user supporting project.
My app will be running in owner. If I switch to user, any related UI actions should be shown on owner or user,
I am using Context.startActivityAsUser(intent, UserHandle.Current);
so the activity will be launched on corresponding user or owner.
the same way to launching broadcast events.
In my app, I am using notification as part of service as below
startForeground (int id, Notification notification);
as the service is running is owner, the notification is showing on owner only even though I switched to user.
When end user switched to other profile, the notification should be shown on current profile.
as per my knowledge, there is no startForeground(...) as user (i mean as startForegroundAsUser()) so I have converted notification stuff to
NotificationManager.notifyAsUser(null, appID, notification, UserHandle.CURRENT);
....
When I switch from owner to user, my app is getting crashed and logs also not clear for find the issue. Logcat just says as
I/ActivityManager(421): Process com.example.test (pid 5833) has died
W/ActivityManager(421): Scheduling restart of crashed service com.example.test/com.example.test.testservice in 1000ms
.....
.....
.....
but the service is not started as top profile is CURRENT.
Let me know the other approach to achieve this.
The short answer is you cannot do this. Each app package is installed on the device with a separate data area and process for each human user. They are purposely kept isolated in memory and filesystem space via Linux UID/GID and permissions. In Android 5.0 this is further enforced using SE Linux for Android. So when you are switching (human) users, your apps are being started as separate instances for that person.
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