I have been developing an app, and I need to close another app in my code. Does anyone know any api to call to close an app?
BTW: my app will be pre-installed.
thanks
Since Android 2.2 (i.e. going forward), you can only close the background processes of other apps, you are no longer able to close their main activities.
If your app is targeting Android <2.2, look atandroid.permission.RESTART_PACKAGE.
If you want it to work properly on 2.2 and above (which you should :-)), look at android.permission.KILL_BACKGROUND_PROCESSES, but again, this only closes background services and such and might "mess up" the other app rather than doing any good.
With the right permissions, you can then do the following:
private ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
am.restartPackage("com.jimmy.appToBeClosed");
Try This
ActivityManager am = (ActivityManager) getApplicationContext().getSystemService("activity");
Method forceStopPackage;
forceStopPackage =am.getClass().getDeclaredMethod("forceStopPackage",String.class);
forceStopPackage.setAccessible(true);
forceStopPackage.invoke(am, pkg);
In manifest file add this
<uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"></uses-permission>
If both applications are yours, you can use AIDL for inter-process communication to send a message telling the other application to close. See http://developer.android.com/guide/developing/tools/aidl.html.
I have been able to close another app on Android 12 successfully. Here is how:
Basically, I am closing another app from a service although you should be able to do it from an app too.
My service is a privileged system app that gets installed in system/priv-app/ (It has LOCAL_PRIVILEGED_MODULE := true in its Android.mk)
I added <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" /> in AndroidManifest.xml
I added in privapp-permissions.xml
<privapp-permissions package="<my service package name>">
<permission name="android.permission.FORCE_STOP_PACKAGES"/>
</privapp-permissions>
I called in my service this method with the package name of the application I want to close:
private void closePackageApp(String namePackage) {
ActivityManager activityManager = (ActivityManager)
context.getSystemService(Context.ACTIVITY_SERVICE);
try {
Method forceStopPackage = activityManager.getClass().
getDeclaredMethod("forceStopPackage", String.class);
forceStopPackage.setAccessible(true);
forceStopPackage.invoke(activityManager, namePackage);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
I tested this and in the logs, I can see the app is being closed. However the app is not removed from the recent screen (logs suggested the app was disposed without first being removed with the input manager!).
However, I am sure the app was really being closed when it was in the background by comparing its lifecycle on opening again. Normally, it is onPause->onResume but now it is onPause->onCreate.
You don't ever really want to close another application, due to Android activity lifecycle.
There's no benefit, and always detriment to closing another app if it's not yours, and very little benefit to closing your own.
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
If you know for certain that you'll never, ever need a root activity and its children (an "app"), you can stop it to free memory (it doesn't free that much), but if you do the user may restart it while it's still in cache, stopped, which can cause problems if the stopped state is restored. So this is a bad practice.
Related
I'm having a MainActivity, which start a foreground service as an intent with the methode ContextCompat.startForegroundService this service has an instance of paho MQTT connection.
When I closed the application, I want to send a last message in MQTT to warn that the application going to be closed, but this didn't work all the time, namely when I'm not connecting to my computer with the android studio debugger.
So have you any idea to help me ?
More informations :
On the onDestroy() methode of MainActivity :
getApplicationContext().stopService(intent);
On the onDestoy() of my service :
client.published(client.GetTopic(),client.TAG_CLOSE);
try {
client.client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
Log.e("destroy service", "ERROR !!!!");
}
EDIT : I discovered that the problem, appear when I turn on the battery saving.
Neither the onDestroy method nor onStop is guaranteed to be called.
There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it.
source: https://developer.android.com/reference/android/app/Activity.html#onDestroy()
I believe this could change from device to device. Your observation that it happened while the battery saving option was ON could be very true in this case.
As for the solution maybe take a look at bound services and see if they are better fit for your scenario: https://developer.android.com/guide/components/bound-services
Stay strong and happy coding!
After the help of Kostek (https://stackoverflow.com/a/71485487/16188409), I found the solution, by adding the "REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" to the manifest as the post below said :
https://stackoverflow.com/a/67770107/16188409
I am building an application that should be able to close other android applications. In this case, I am using Google Maps. I have granted permission in the Android Manifest XML to killBackgroundProcesses, but the following code does not close the "Google Maps" application. My app calls killApp() every second to ensure Google Maps is closed. Any idea what I'm doing wrong here?
public void KillApp()
{
Context context = getContext();
String maps = "com.google.android.apps.maps";
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.killBackgroundProcesses(maps);
}
You can only kill your own apps, e.g. the ones running in the same process or with the same userID. You can not kill others, unless the device is rooted.No one can kill process except Android OS itself.
Most of the task killer in android market don't kill the app they just restart the process
by using
public void restartPackage (String packageName)
when this method is called by your activity the operating system immediately called
savedInstanceState and save the state of that activity you want to kill. Now this process is
removed from memory and OS saved it state.Now when next time user start that activity it
will start from where it was killed or in other words restarted. You can verify it from any
task manager that they don't kill the process because no one can do so. This method also
work in ICS.
for above method you can look at here . As far as i know killBackgroundProcesses (String packageName) is for API 8 and above.
I'd like to force stop my Android application when I click closeButton. This is my code.
protected void onCreate(Bundle savedInstanceState) {
this.setContentView(R.layout.layoutxml);
this.closeButton = (Button)this.findViewById(R.id.close);
this.closeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
This finishes my application. If I go to Settings -> Applications -> Manage applications -> <my application name>, I can see the 'Force Stop' button is enabled. Does this mean my application was not stopped completely?
How can I finish my Android application completely and disable the 'Force Stop' button inthe 'Settings'? From my limited experience, when an 'Exception' (ex. NullPointerException) occurs in the application, it stops abnormally, looks like it finished completely, and the 'Force Stop' button looks disabled.
Another way is
android.os.Process.killProcess(android.os.Process.myPid());
I don't think it's all that bad to do this, provided you put those calls in onDestroy(). (If you kill your process in the middle of event handling, all kinds of bad things—like the touch focus going into the ether—can happen.)
Nevertheless, you need a compelling reason to deviate from best practice, which is to just call finish() and let the OS take care of killing off your process when/if it needs to.
Note: This does not kill the entire app, but if what you want to do is to finish all the app activities, this is the best option.
Android ≥ 16
finishAffinity();
Android < 16
ActivityCompat.finishAffinity(Activity activity)
Hope this helps
A bad way to kill the application would be System.exit(0)
Edit:
I believe I owe some explanation. Android handles the application lifecycle on its own, and you are not supposed to 'ForceClose' it, and I don't know any good way to do it. Generally its ok if your application is still alive in the background, this way if user launches it again it will pop up quickly.
I know it is a late reply , hope this helps some one.
You can try finishAndRemoveTasks(); instead of finish(); in your snippet.
This would kill your application's all activities and all process and even remove for recent apps from task manager.
Note: If you have use any kind of handler or thread in your code make sure you remove its functionalities and then use the above suggested code , if not NullPointer Exception or ResourceNotFound Exception would occur.
Short and simple
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory( Intent.CATEGORY_HOME );
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);
Why not to make a Shell-Call to ActivityManager?
try {
Runtime.getRuntime().exec("am force-stop com.me.myapp");
} catch (IOException e) {
e.printStackTrace();
}
The link below has the solution.
Its worked for me.
finishAffinity()
How to force stop my android application programmatically?
I need to understand how a message traverses the Android system from the service level down to the driver calls.
I have decided to start with WiFi, although my current hardware platform - a Beaglebone Black board with TI's Rowboat (Android 4.2.2) - does not have WiFi capability.
My plan is to insert logging function calls to the source code and send an Intent to WifiService through the am program in order to trigger the messages towards the driver.
I have found, in init.rc, that ServiceManager is started through the following code
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
Furthermore, from frameworks/base/services/java/com/android/server/SystemServer.java, I have found this code snippet
try {
Slog.i(TAG, "Wi-Fi Service");
wifi = new WifiService(context);
ServiceManager.addService(Context.WIFI_SERVICE, wifi);
} catch (Throwable e) {
reportWtf("starting Wi-Fi Service", e);
}
which, I believe, starts WifiService.
However, I cannot determine how SystemServer is started.
Besides that, I managed to insert a log function at frameworks/base/wifi/java/android/net/wifi/WifiManager.java, as follows
public WifiManager(Context context, IWifiManager service) {
mContext = context;
mService = service;
Log.i(TAG, "WiFiManager Created. Calling init()"); // inserted log
init();
}
and I can see it working through the use of logcat -s WifiManager, which results in
I/WifiManager( 317): WiFiManager Created. Calling init()
I/WifiManager( 396): WiFiManager Created. Calling init()
I/WifiManager( 968): WiFiManager Created. Calling init()
Nevertheless, I cannot determine why it is called 3 times or where the calls came from.
As for C code, I hope to see its log messages by using dmesg.
I have cscope and ctags configured to browse the code but I cannot manage to find what comes below WifiService or WifiManager.
It looks like I still have a long road ahead, so any help would be greatly appreciated.
Slide 8 from this presentation might be able to answer a couple of your questions
The sources for the WifiService and WifiController might be of help as well, you can find them in frameworks/base/services/java/com/android/server/wifi. Also check the README.txt in there.
I am trying to build a task killer type of app in android. I can show the list of currently running task using ActivityManager but facing problem in killing the task.
Here is what i am doing to get the list of currently running task :
ActivityManager am = (ActivityManager) context.
getSystemService(Activity.ACTIVITY_SERVICE);
List<RunningTaskInfo> a = am.getRunningTasks(Integer.MAX_VALUE);
PackageManager pack = this.getPackageManager();
for(int i = 0; i < a.size(); i++) {
String packageName = a.get(i).topActivity.getPackageName();
Drawable d = null;
String appName = "";
try {
d = pack.getApplicationIcon(packageName);
appName = (String)pack.getApplicationLabel(pack.getApplicationInfo(packageName,PackageManager.GET_META_DATA));
} catch (NameNotFoundException e) {
e.printStackTrace();
}
packName.add(packageName); //arraylist of package name
apps.add(appName); // arraylist of app name
icons.add(d); //arraylist of icons
}
It worked for me But now as I am trying to kill the task using killBackgroundProcesses :
am.killBackgroundProcesses(package name);
It did not work . Also killBackgroundProcesses method is available in API level 2.2 then how can i perform the same task in previous API level such as 1.6 etc.
Is there any other way to show the currently active apps and kill them?
No one can kill process except Android OS itself.
Most of the task killer in android market don't kill the app they just restart the process
by using
public void restartPackage (String packageName)
when this method is called by your activity the operating system immediately called
savedInstanceState and save the state of that activity you want to kill. Now this process is
removed from memory and OS saved it state.Now when next time user start that activity it
will start from where it was killed or in other words restarted. You can verify it from any
task manager that they don't kill the process because no one can do so. This method also
work in ICS.
for above method you can look at here . As far as i know killBackgroundProcesses (String packageName) is for API 8 and above.
In a nutshell, Automatic Task Killers work by polling the OS for a list of currently running processes and the memory they are consuming. Then either with an intelligent algorithm or with user input the Task Killers issue a call to the system telling the system to kill the process. There are two apis you can do this.
They are
Process.sendSignal(pid, Process.SIGNAL_KILL);
ActivityManager.killBackgroundProcesses(PackageName)
This first works by invoking Process.killProcess(int pid) where pid is the unique identifier for a specific process. Android kills processes in the same way that linux does; however, a user may only kill processes that they own. In Android each app is run with a unique UID, user ID. So using this API an App can only kill its own processes, hence the following explanation in the docs for Process.killProcess(int pid):
Kill the process with the given PID. Note that, though this API allows
us to request to kill any process based on its PID, the kernel will
still impose standard restrictions on which PIDs you are actually able
to kill. Typically this means only the process running the caller's
packages/application and any additional processes created by that app;
packages sharing a common UID will also be able to kill each other's
processes.
When this method is called the signals is generated by the OS and set to the process. Whenever a process receives a signal from the OS it must either handle that signal or immediately die. Signals such as SIG_KILL cannot be handled and result in the immediate death of the recipient process. If you want to kill processes that you don't have privileges to kill, i.e. its not your process, then you must escalate your privileges using sudo (this would require root privileges on the device).
The second API works by telling the ActivityManager that you wan to kill processes associated with a specific Package. This API gets around the need for your UID to match the UID of the process because it requires the user to accept the KILL_BACKGROUND_PROCESSES permission. This permission signals to the OS that an app has been approved by the user as a task killer. When a task killer wants to kill an app, it tells the OS to do it getting around the problem of only being able to kill processes that you own.
In the Android Docs it says that this API actually uses the first Process.killProcess API
Have the system immediately kill all background processes associated
with the given package. This is the same as the kernel killing those
processes to reclaim memory; the system will take care of restarting
these processes in the future as needed.
Hope It Helps.
Did you enter below permission in the manifest file?
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>