How to uninstall a running app through code? - android

I have a requirement in my app that after a specified number of unsuccessful login attempts:
A folder on the sdcard essential for the app be deleted and
The app be uninstalled from the device.
This is basically a self destruct sort of action.
Can you provide inputs on whether the aspect of uninstalling the app, while the app is running is feasible? I assume deletion of the folder must be easy. Do you foresee any issues with doing that too.
Thanks
A

There's no public API to allow you to seamlessly remove a package (including your own.) You can request a package be removed by firing an Intent with the action set to ACTION_UNINSTALL_PACKAGE, but the user will be notified of the action as it will take them to the default installer (ie Google Play Store) to perform the action.

Larry Schiefer is right, there is (fortunately) no public API to do this without user interaction. But if you have extended rights, for example if the device is rooted and your app has root access, you could use the command line:
Runtime.getRuntime().exec(new String[] {"su", "pm uninstall com.example.yourapplication"})
In the case you have special privileges because you are a system app, you can use hidden API's, which are very dangerous because they are undocumented and can change from one Android update to the next. However, if you are in control which version of the OS installed, you might get away with it.
In this case, you could call PackageManager.deletePackage through reflection.
pm = context.getPackageManager();
Class<?>[] types = new Class[] {String.class, IPackageDeleteObserver.class, int.class};
method = pm.getClass().getMethod("deletePackage", types);
method.invoke(pm, new Object[] {"com.example.com", null, 0})
This function should also delete all your package data, so it's a complete wipe. You need to ask for the DELETE_PACKAGES permission in your AndroidManifest.xml (which is only granted if you are a system app/system user):
<uses-permission android:name="android.permission.DELETE_PACKAGES"/>

Related

Permission handling for privileged system apps

I'm writing an Android app, that will run on custom hardware with a ROM that I have control of.
The device will run a single application (as a launcher) and once the device is deployed I (generally) do not have access to it anymore. The app also has support for updating itself.
As such, I need a way to properly handle permissions for the app i.e. permissions need to be granted automatically (including dangerous ones) if they are ever added to the manifest.
Now, the app is being signed by the same certificate as the Android OS running on the device, and the app is placed in the priv-app directory when the device is flashed.
I assumed that this would automatically grant permissions but this does not appear to be the case.
I have tried adding android:sharedUserId="android.uid.system" to the manifest, and that does indeed grant all permissions, but since there are already quite a few legacy devices "in the wild", adding this option makes it so that the app can no longer be updated (throwing a INSTALL_FAILED_SHARED_USER_INCOMPATIBLE error).
So, what is the best way to handle permissions in this case? Is there some other voodoo magic I am missing here? Should I just bite the bullet, add the sharedUserId option and manually update all devices (undesired, but possible option)?

Android Do not Disturb (DnD) permission in managed profile

I have the following problem:
My app is distributed over an MDM system and runs in Android for Work.
In certain situation, the app must temporarily terminate the DnD mode. To achieve this, the user must grant the DnD permission when the app is started.
So far so good. If I install the app in the unmanaged area, the app shows up in the list and the permission can be granted without any problems.
As soon as the app is distributed via an MDM system, the app no longer appears in the list and the permission cannot be granted. All authorizations have been granted in the MDM system. As an example, I have distributed the Google App over the MDM system. This app appears in the list.
In the Manifest I have set the following permission:
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
When the app is started, the following code is executed:
NotificationManager nm = (NotificationManager).getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M && !nm.isNotificationPolicyAccessGranted()) {
Intent intent = new
Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivity(intent);
}
The problem only occurs with DnD permission. All other permissions such as overlay permission, are displayed without problems.
I hope anyone can help me.
According to Android documentation: NOT POSSIBLE
Users can grant and deny access to Do Not Disturb configuration from here. Managed profiles cannot grant Do Not Disturb access.
I haven't found a proper solution for the problem yet but I found a workaround to display the app in the work area. It seems that the app is only displayed in the dialog if the same app is also installed in the private area.
If the app is not installed in the private area, it will also not appear in the work area.
My workaround was to install the app in the private and work area. After the permission in the work area was granted, I removed the app from the private area. Like I said, it's not a solution to the problem itself, but it worked.
To me this looks like a bug in Android, because for all other permissions the app appears in the list
Apparently there is issure reported regarding this on Google Issue Tracker
https://issuetracker.google.com/issues/77939714
This is the reply from Google:
Status: Won't Fix (Intended Behavior) 11:41AM You can not change DND
settings from a managed profile app. We will be updating the
documentation to clarify this.
There is also a reply stating:
Microsoft Intune has released their fully managed Android Enterprise
profile setup for Android Devices. ... and it can now access and
grant the DnD permission. Not sure if its the fact that we have gone
to fully managed devices or if something else has changed.
And I would believe this is actually because the device is fully managed.
So according to my understadning there are two options:
Fully managed device (will require a factory reset on the phone)
Install it on the personal profile
We have the same issue with the app SignOnSite. Can't get access to the DnD function for emergency evacuations unless we also install the app in the Personal space as well. Makes it to risky doing it this way, so ended up just installing the app in the Personal space.
Using Intune for our MDM.
Try this -
Intent intent = new Intent("android.settings.NOTIFICATION_POLICY_ACCESS_SETTINGS");
startActivity(intent);

Delete system cache on android 6.0

I'm using method freeStorageAndNotify() with permission android.permission.CLEAR_APP_CACHE to delete system cache of all installed applications. But the method started throwing InvocationTargetException from the android marshmallow 6.0 version.
After googling the issues I found the same issue as reported here:
Android M reflection method freeStorageAndNotify exception
So here the conclusion was, freeStorageAndNotify() stopped working since google has raised the method's signature level now to signature|system.
But now the question is how other third-party apps like 'Clean master' are still able to delete system cache of all installed applications by taking accessibility permission from the user for 6.0 devices?
I don't think that 'Clean master' actually uses Accessibility Permissions to clean installed apps cache.
But, if you're interested, this goal can be achieved by using AccessibilityService in your application.
Within your class that extends AccessibilityService you have this callback:
#Override
public void onAccessibilityEvent(AccessibilityEvent aEvent) {
AccessibilityNodeInfo rootNode = aEvent.getSource();
//...
}
Here you can invoke
rootNode.findAccessibilityNodeInfosByViewId()
or
rootNode.findAccessibilityNodeInfosByText(),
it will return all matching AccessibilityNodeInfo objects (sub-nodes) in tree. Then, you just need to detect which of them is Button (node.getClassName()) and call subNode.performAction(AccessibilityNodeInfo.ACTION_CLICK).
On Android M, you first need to to open system's App Info screen (you can find instructions here How can I start android application info screen programmatically?) for the concrete app and, by the scheme described above, perform sequential clicks on the buttons "Storage" —> "Clear cache".
In order to clear cache for all installed apps you probably have to iterate through the all installed apps (List<ApplicationInfo> installedApplications = context.getPackageManager.getInstalledApplications(0);)
and repeat the procedure mentioned above.
The system cleaner I'm using has access to the STORAGE permissions. This permission gives the app authority to clear any data in the shared external storage directory.
http://developer.android.com/reference/android/Manifest.permission_group.html#STORAGE
I don't think any 3rd party app can actually clear system cache anymore unless the device is rooted and the app is designed for rooted devices.
those apps only do the same thing all the time. use it on an old device and a new device the results are the same. the only help i have seen is that they can kill or restart some background processes, not to clean the cache. therefore no API can restrict their trick..

how to disable run the app by BOOT_COMPLETED

i want to do a task manager soft,i want to check all apps which used android.intent.action.BOOT_COMPLETED and i want to also disable Auto Startup when the mobile start run. i have no clue,if i need the root permission to finish it any advice may receive
To check which applications receive BOOT_COMPLETED intent action you can use android PackageManager and ResolveInfo class something like,
Intent intent = new Intent(android.intent.action.BOOT_COMPLETED);
List<ResolveInfo> listApp = packageManager.queryIntentActivities(intent, 0);
for (ResolveInfo res : listApp) {
Log.e("Camera Application Package Name and Activity Name",res.activityInfo.packageName + " " + res.activityInfo.name));
}
But I think its not possible to change other application's permission which they are used. So you can't prevent it to start at BOOT_COMPLETED time.If you want to this then for this you have to ROOT permission.
There is one of application on android market that allow you to do it, for example LBE Privacy Guard
UPDATE:
In android framework structure, in /data/system/packages.xml which contains all installed application's information include used permission, (I never try this also don't know whether its worked or not) If you can modify this file then may be you can achieve what you want..
Thanks..
Note you can not change the /data/system/packages.xml file above to remove the android.intent.action.BOOT_COMPLETED permission.
This is because the android framework, at start-up, parses every apk (i.e. app) manifest file and when it sees the android.intent.action.BOOT_COMPLETED permission, it calls the app at that time.
Therefore, modifying the file will have no effect. I've tried this - believe me. The only way I know of to remove the android.intent.action.BOOT_COMPLETED permission (aside from modifying the andorid framework, recompiling it, and loading it onto your phone) is to manually edit the apk files you want to remove the permission from.
Obviously not for the faint of heart!
If you can find out what the component is (e.g., by looking at the app's manifest), you can disable the component from an adb commandline or a root shell with: pm disable package.name/component.class.name
The Autostarts app does this. It has GPL (I think) source code that you can re-use for your app if your app is GPL, too.

rebooting Android phone - permission denial

I am trying to reboot (through code) the phone at some point. In order to do that I do this:
Intent i = new Intent(android.content.Intent.ACTION_REBOOT);
i.putExtra("nowait", 1);
i.putExtra("interval", 1);
i.putExtra("window", 0);
this.sendBroadcast(i);
The problem is that, even if I have in the manifest this line:
uses-permission android:name="android.permission.REBOOT" (with the delimiters).
When trying to execute it, it gives me the next error:
Permission Denial: not allowed to send broadcast android.intent.action.REBOOT from pid= uid= gids=
I read that you should create an .apk and sign it with SignApk, but I created the key/certificate with openssl and signed with those and this didn't run either, I continue getting exactly the same error.
Do you have any clue about how to solve this and being able to reboot the phone? I do really need to do it.
public static final String ACTION_REBOOT
Since: API Level 1
Broadcast Action: Have the device reboot. **This is only for use by system code.**
**This is a protected intent that can only be sent by the system.**
Constant Value: "android.intent.action.REBOOT"
http://developer.android.com/reference/android/content/Intent.html#ACTION_REBOOT
So, unless you go off band and rely on having SuperUser you wont be able to force a reboot.
Why does my app throw an `android.permission.REBOOT SecurityException`?
From what I understand, the permission REBOOT is only available to apps signed by the key that signed the hardware, ie system apps
For rebooting Android device through code u need "android.intent.action.REBOOT" permission which is granted only to the system applications or to the application which are signed with the same key as that of system applications. Apart from this one also has to add a tag in Android Manifest android:sharedUserId="android.uid.system". So as to insure application shares the same uid as that of system application.
The key used for signing system app. is unique to device manufacturer and it cant be duplicated.
Android applications are not allowed to send android.content.Intent.ACTION_REBOOT
See the note here http://www.google.com/codesearch/p?hl=en#5oTG8Wvrixk/trunk/android-x86/frameworks/base/core/java/android/content/Intent.java&l=1510
/**
* Broadcast Action: Have the device reboot. This is only for use by
* system code.
*/
#SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_REBOOT =
"android.intent.action.REBOOT";
http://www.krvarma.com/posts/android/security-permissions-in-android/
Permissions are granted to the application by package installer while installing. But not all the permissions will be granted to the system. There are some system permission which will not be granted to the user applications, but only to the system applications. Following are some of the permissions that may NOT be granted to the user application.
To get these permissions, the application must be signed with the key which used to sign the platform. This may be different for manufacturers. So it practically not possible to get these permissions granted to a user application.

Categories

Resources