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"/>
Related
I use Java JNA to execute Windows API commands.
I have a background service running as local-system.
From this background service, I'd like to spawn a new process, e.g. notepad.exe on the currently active desktop and user. The new process should not run elevated but with the active logged-in users rights.
I use
WTSGetActiveConsoleSessionId to get the active session
WTSQueryUserToken to get the related token
CreateProcessAsUser to start the process
This works fine if I build a jar and launch the jar with java -jar my.jar from the local-system account.
However, I run the code from an Install4j Installer, which is, more or less, a JVM wrapped in an exe. The same code fails now, and CreateProcessAsUser results in error code 5 (no access)
I compared the tokens, and could not find any difference. Same user, owner, groups, and privileges.
I tried using process monitor to find anything special: nothing
I tried to use CreateProcessWithTokenW instead of CreateProcessAsUser. The process launches but exits immediately(Maybe a Windowstation/Desktop issue)
Expected result: The "child" process starts and shows the UI on the currently active desktop.
Actual result: Errorcode 5 on CreateProcessAsUser
final PROCESS_INFORMATION processInformation = new PROCESS_INFORMATION();
final int activeConsoleSessionId = Kernel32Ext.INSTANCE.WTSGetActiveConsoleSessionId();
final PointerByReference userPrimaryProcessToken = new PointerByReference();
if (!Wtsapi32Ext.INSTANCE.WTSQueryUserToken(activeConsoleSessionId, userPrimaryProcessToken)) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
final STARTUPINFO startupInfo = new STARTUPINFO();
startupInfo.clear();
startupInfo.lpDesktop = "winsta0\\default";
startupInfo.wShowWindow = new WORD(1);
startupInfo.cb = new DWORD(processInformation.size());
final String cmdString = "C:\\Windows\\System32\\notepad.exe";
if (!AdvapiExt.INSTANCE.CreateProcessAsUser(new HANDLE(userPrimaryProcessToken.getValue()), null, cmdString, null, null, true, Kernel32.CREATE_UNICODE_ENVIRONMENT, null, "c:\\", startupInfo, processInformation)) {
final int error = Kernel32.INSTANCE.GetLastError();
throw new Win32Exception(error);
}
This is not a real answer, but after a system restart and windows updates, I cannot reproduce the problem anymore. If I ever manage to reproduce it again, I will continue the investigation.
A few things a noticed before the problem "disappeared":
1.
Before updating windows, I enabled the program execution audit(local security policies), and saw in the windows logs, that, according to the logs, the application got started, even there was no window or running process, and the CreateProcessAsUser returned with an error...
2.
The problem did only happen if services.exe was in the calling-chain. If I started the application directly via psexe as a local system process, everything went fine.
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'm trying to use ODB Java API (this library) to get the data from ELM327 via Bluetooth from my car, but in returns ? on every request, and library raises MisunderstoodException
Here is my code:
socket = device.createInsecureRfcommSocketToServiceRecord(uuid);
socket.connect();
final CustomRPMCommand engineRpmCommand = new CustomRPMCommand();
final SpeedObdCommand speedObdCommand = new SpeedObdCommand();
while (!Thread.currentThread().isInterrupted()) {
engineRpmCommand.run(socket.getInputStream(), socket.getOutputStream());
speedObdCommand.run(socket.getInputStream(), socket.getOutputStream());
runOnUiThread(new Runnable() {
#Override
public void run() {
speedometerGauge.setSpeed(engineRpmCommand.getRPM(), true);
rpmGauge.setSpeed(speedObdCommand.getMetricSpeed(), true);
}
});
}
What's wrong?
I also used the same library for the first steps into trying out OBD, so I can say at least at the time I used it, it worked fine.
From my experience however, getting ? back can sometimes happen with cheap Bluetooth devices (maybe even with expensive ones? never had one). I guess this happens, if some bits are lost during the transmission, because then command will be misunderstood.
What I did to circumvent this problem is setting up a process where I sent all AT commands up to 10 times until I get the desired response of OK (except for ATZ, which will respond with ELM327). As for value requests like RPM etc. I usually just throw away the erroneous values.
That's the short answer, but since such problems with the devices can annoy a lot, I will guide you into debugging the whole process...
Setting up a terminal on windows
First of all to test the functionality of the ELM device, you can send commands to the serial interface directly. On windows, this is possible using for example TeraTerm and then setting up new Bluetooth connection on your windows as a COM device (search for Bluetooth in start -> search box and then choose Change Bluetooth settings or similar). From there, go to COM connections and then add a new one Outgoing for the Bluetooth OBDII device. Wait a bit for windows to calculate the new COM port number, you will need it.
If you cannot find OBDII in the dropdown box, you have to bond your PC with your Bluetooth device first. This can be done via devices and printers, there you should see the OBDII device, so you only have to connect it (PIN usually is 1234).
If you're on Linux, it might be somewhat easier, but I haven't done it :)
Sending some commands via terminal
Once you have your Bluetooth connection and TeraTerm installed, you can start TeraTerm and connect to the adapter. Choose Serial and then the port you just set up. Ensure, that no other device is connected to the OBD adapter (also not your phone). Only one device can be connected at a time.
If connection was successful, you should be able to type letters. Usually, in default settings you should be able to see the letters you type (Echo mode on), but since this is not certain, just type ATZ and hit <Enter>. The ELM should respond with "ELM327" in the same line now (which for me usually results in odd display if echo mode was on, but you should get any response).
From terminal I usually send these commands in order:
ATZ
E1
L1
010c
This will trigger:
Reset of the OBD device
Make sure that echo is on, so I see what I am typing
Make sure Line feed is on, so we get responses in the next line
Request RPM from the vehicle
Between each command I'll check what is the reply of the device. For all AT commands (1., 2. and 3.) it must be OK. If I get back ?, which can happen, I will repeat the command another time. You will see that in such a case the device indeed did not follow the instructions, e.g. did not set line feed on if it was off. So we really have to send it again.
In programming mode on the other hand, we will set e0 and l0 (echo mode off and line feed off), because we do not want to get sent back what we already sent out.
I am working on a third-party library for Android and need to be able to tell if I am running as a privileged process with my desired permissions, or if I am living in an isolated process with restricted permissions as defined in the AndroidManifest.xml file:
<service android:name="mySandboxedService" android:permission="com.android.chrome.permission.CHILD_SERVICE" android:exported="false" android:process=":sandboxed_process0" android:isolatedProcess="true" />
The reason being that certain things I'm trying to do, such as get the number of running application processes (and various other things), will throw a RuntimeException if they are isolated. This code will run successfully if not run as an isolated process, but will throw RTE if the process is isolated:
ActivityManager aM = (ActivityManager) context.getSystemService(android.content.Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> l = null;
try {
l = aM.getRunningAppProcesses();
} catch (RuntimeException e) {
Log.w(LOGTAG, "Isolated process not allowed allowed to call getRunningAppProcesses, cannot get number of running apps.");
}
From my logcat:
java.lang.SecurityException: Isolated process not allowed to call getRunningAppProcesses
Does anyone know of a way I can check my current process to see if it is isolated or privileged? I've checked the Android Service doc here, and it does not provide much information.
My end goal is to initialize my app once from the main, privileged thread, and then ignore all of the startup calls from the various sandboxed processes that may get created. I don't want to run in those, but my hook is in Application.onCreate and gets called for every process, sandboxed or not.
I've considered the idea of adding one of these checks to my initialization and catching the RTE if it's thrown. But if there is a public API for it, I'd rather use that.
One can check the uid of the running process to see if they fall in the range of isolated process.
int AID_ISOLATED_START = 99000;
int AID_ISOLATED_END = 99999;
int uid = Process.myUid();
if (uid >= AID_ISOLATED_START && uid <= AID_ISOLATED_END) {
Log.i(TAG, "This is from an isolated process");
}
Process range info source: https://android.googlesource.com/platform/system/sepolicy/+/master/public/isolated_app.te
EDIT: The above has been found to be unreliable on Android 8.1 and below.
Another approach is to try accessing privileged APIs and see if an exception is thrown.
try {
ActivityManager activityManager = (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
activityManager.getRunningAppProcesses();
} catch (SecurityException e) {
Log.i(TAG, "This is from an isolated process");
}
As pointed out in an other answer, Android Pie/9 (API 28) introduced a new API for this. See https://developer.android.com/reference/android/os/Process#isIsolated().
This seems to be present in versions as low as Android 4.3. See https://cs.android.com/android/platform/superproject/+/android-4.3.1_r1:frameworks/base/core/java/android/os/Process.java;l=680
API 28 (Android Pie / 9) introduced new method for checking if current process is an isolated one: Process#isIsolated.
Note that this method was added to Process class in API 16, but was hidden till API 28. Therefore the following method can be used to check if the process is isolated or not (this is actually how Chrome app performs this check):
#SuppressLint("NewApi")
public boolean isIsolated() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
return false;
}
return android.os.Process.isIsolated();
}
Checking if the UID is in the {99000, 99999} range (as demonstrated in the accepted answer) will produce incorrect results in multi-user/profile environment for all users/profiles which are not the main one - since their UIDs will be prefixed with matching user id (example UID for user 10's isolated process will be 1099013).
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.