I want to find all apps with enabled SYSTEM_ALERT_WINDOW permission installed on the device.
First of all I found all apps with SYSTEM_ALERT_WINDOW permission and I verified that the list is correct: on my phone I went to Settings -> Special app access -> Display over other apps.
Then I disabled "Allow display over other apps" option for all apps under "Display over other apps" menu.
Next, I started my app again and I found out that list of apps with SYSTEM_ALERT_WINDOW permission still the same.
I decided to check if permission is granted or not. I used the following:
PackageManager.checkPermission(SYSTEM_ALERT_WINDOW, package name) == PackageManager.PERMISSION_GRANTED
But this check returned true for all packages with SYSTEM_ALERT_WINDOW permisson! Moreover, this check returns true even if package doesn't have SYSTEM_ALERT_WINDOW permission at all.
My code is below:
public ArrayList<String> getAppsWhichHaveOverlaySettingEnabled() {
ArrayList<String> apps = new ArrayList<>();
PackageManager pm = getPackageManager();
List<PackageInfo> installedPackages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS);
for (PackageInfo packageInfo : installedPackages) {
String[] requestedPermissions = packageInfo.requestedPermissions;
if (requestedPermissions != null) {
for (String requestedPermission : requestedPermissions) {
if (requestedPermission.equals(SYSTEM_ALERT_WINDOW)) {
if (pm.checkPermission(SYSTEM_ALERT_WINDOW, packageInfo.packageName) == PackageManager.PERMISSION_GRANTED) {
String name = pm.getApplicationLabel(packageInfo.applicationInfo).toString();
apps.add(name + " (" + packageInfo.packageName + ")");
}
}
}
}
}
return apps;
}
What am I doing wrong? Or it is not possible to get such information at all?
I checked my method and another app with similar method on several Android devices and looks like it is not possible to get list of apps with currently enabled SYSTEM_ALERT_WINDOW permission.
If SYSTEM_ALERT_WINDOW permission was granted to app once then check methods will return true no matter whether this permission currently enabled or not.
Still, the more accurate way to check such a permission is:
public ArrayList<String> getAppsWhichHaveOverlaySettingEnabled() {
ArrayList<String> apps = new ArrayList<>();
PackageManager pm = getPackageManager();
List<PackageInfo> installedPackages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS);
for (PackageInfo packageInfo : installedPackages) {
String[] requestedPermissions = packageInfo.requestedPermissions;
if (requestedPermissions != null) {
for (int i = 0; i < requestedPermissions.length; i++) {
String requestedPermission = requestedPermissions[i];
if (requestedPermission.equals(SYSTEM_ALERT_WINDOW)) {
if ((packageInfo.requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) == REQUESTED_PERMISSION_GRANTED) {
String name = pm.getApplicationLabel(packageInfo.applicationInfo).toString();
apps.add(name + " (" + packageInfo.packageName + ")");
}
}
}
}
}
return apps;
}
Read more here.
Related
I am developing an android application that will display all the applications installed in the mobile phone and when clicking on a particular application, it should show only permissions of that application. I used package manager to fetch the details of all the details of the apk's installed.
The part of the code is here:
PackageManager packageManager = context.getPackageManager();
List<PackageInfo> applist = packageManager.getInstalledPackages(0);
Iterator<PackageInfo> it = applist.iterator();
while (it.hasNext()) {
PackageInfo pk = (PackageInfo) it.next();
PackageInfo pk1 = (PackageInfo) it.next();
if ((pk.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
// Log.v("System app using internet = ",""+ pk.applicationInfo.loadLabel(packageManager));
String p = pk.applicationInfo.loadLabel(packageManager).toString();
if (PackageManager.PERMISSION_GRANTED == packageManager.checkPermission(Manifest.permission.CAMERA, pk.packageName))
//results.add("" +"\n"+pk.applicationInfo.loadLabel(packageManager));
{
//Drawable appicon = getPackageManager().getApplicationIcon("com.google.maps");
results.add("" + "\n" + pk.applicationInfo.loadLabel(packageManager));
}
if (PackageManager.PERMISSION_GRANTED == packageManager.checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, pk.packageName))
results1.add("" +"\n"+pk1.applicationInfo.loadLabel(packageManager));
}
}
I should get the icons followed by the application name while listing the applications.
Icon and application name example
How should I modify this code so that the required output is got.
Example app
Official document
core code:
packageInfo.requestedPermissions?.forEach { permission -> ... }
More links
https://developer.android.com/reference/android/Manifest.permission.html
https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml
http://androidpermissions.com/
This question already has answers here:
Determine list of permissions used by an installed application in Android
(4 answers)
Closed 9 years ago.
Some Android apps use its permission to send SMS to a phone number to extract money from the user.
How to detect which Android apps use its permission to send SMS messages?
this might help
final PackageManager pm = getPackageManager();
final List<ApplicationInfo> Apps = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for ( ApplicationInfo app : Apps ) {
// Info we can fetch app.packageName,app.uid, app.sourceDir
// for Permissions:
StringBuffer permissions = new StringBuffer();
try {
PackageInfo packageInfo = pm.getPackageInfo(app.packageName, PackageManager.GET_PERMISSIONS);
String[] requestedPermissions = packageInfo.requestedPermissions;
if ( requestedPermissions != null ) {
for (int i = 0; i < requestedPermissions.length; i++) {
permissions.append(requestedPermissions[i] + "\n");
}
// fetch permissions
}
}
catch ( PackageManager.NameNotFoundException e ) {
e.printStackTrace();
}
}
I am trying to get a list of applications that uses my location permission in my applications and I'm trying to get the applications that uses the location permission:
public void getPermissions(Context context) {
PackageManager packageManager = context.getPackageManager();
final List<PackageInfo> apps = context.getPackageManager()
.getInstalledPackages(PackageManager.GET_PERMISSIONS);
for (PackageInfo pi : apps) {
String[] permissions = pi.requestedPermissions;
if (permissions != null) {
for (String permission : permissions) {
Log.d("TAG", permission);
if (permission.equals("android.permission.ACCESS_FINE_LOCATION") || permission.equals("android.permission.ACCESS_COARSE_LOCATION") || permission.equals("android.permission.ACCESS_MOCK_LOCATION") || permission.equals("android.permission.ACCESS_LOCATION_EXTRA_COMMANDS") || permission.equals("android.permission.ACCESS_INSTALL_LOCATION_PROVIDER")) {
String appname=pi.applicationInfo.loadLabel(packageManager).toString();
//ImageView appicon;
//appicon = pi.applicationInfo.setImageDrawable(packageManager);
// Log.e("TAG", "Permission found for "+ appname);
locationArray.add(appname);
}
}
}
}
} //end of getPermissions method
But with this i will get multiple entries like
Angry Birds
Angry Birds
CWM
CWM
CWM
Facebook
Is there any workaround to solve this?
It's normal to get duplicate entries because you step over all the permissions of a PackageInfo and test each one to see if it is one of the location related permission. For example, as you iterate the permission of the Angry Birds game you'll come across two permission(if I'm not mistaken ACCESS_FINE and ACCESS_COARSE) and because those permissions both fulfill the if condition you'll end up adding the Angry Birds two times.
The trick is to break out of the for (String permission : permissions) when you find the first permission:
for (String permission : permissions) {
Log.d("TAG", permission);
if (permission.equals("android.permission.ACCESS_FINE_LOCATION") || permission.equals("android.permission.ACCESS_COARSE_LOCATION") || permission.equals("android.permission.ACCESS_MOCK_LOCATION") || permission.equals("android.permission.ACCESS_LOCATION_EXTRA_COMMANDS") || permission.equals("android.permission.ACCESS_INSTALL_LOCATION_PROVIDER")) {
String appname=pi.applicationInfo.loadLabel(packageManager).toString();
//ImageView appicon;
//appicon = pi.applicationInfo.setImageDrawable(packageManager);
// Log.e("TAG", "Permission found for "+ appname);
locationArray.add(appname);
break;
}
}
If You do not want duplicates You can add all contents of locationArray to HashSet(which will not allow duplicates) and add HashSet back to locationArray.
// add elements to hs, including duplicates
HashSet hs = new HashSet();
hs.addAll(localArray);
localArray.clear();
localArray.addAll(hs);
Now localArray will not have any duplicates.
How do I check for a specific permission in the manifest.xml from code? I want to throw some exception if some permissions that are necessay for my application are missing.
For example, FINE_LOCATION and COARSE_LOCATION I know that android will also throw an exception on the launch of the specific activiy that is using GPS, but I need to check the manifest and throw an exception at the launch of the application itself. This holds not only for location access, but also for other permissions.
Any suggestions would be helpful.
You can check whether the permission is granted or not for specific permission by using PackageManager. For example
PackageManager pm = getPackageManager();
if (pm.checkPermission(permission.FINE_LOCATION, getPackageName()) == PackageManager.PERMISSION_GRANTED) {
// do something
} else {
// do something
}
You can read the available <uses-permission> tags at runtime using the following. Tested on older Android versions AND Android 6 and 7
PackageManager pm = getPackageManager();
try
{
PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), PackageManager.GET_PERMISSIONS);
String[] requestedPermissions = null;
if (packageInfo != null) {
requestedPermissions = packageInfo.requestedPermissions;
}
if (requestedPermissions != null && requestedPermissions.length > 0)
{
List<String> requestedPermissionsList = Arrays.asList(requestedPermissions);
ArrayList<String> requestedPermissionsArrayList = new ArrayList<String>();
requestedPermissionsArrayList.addAll(requestedPermissionsList);
Log.i(ExConsts.TAG, ""+requestedPermissionsArrayList);
}
}
catch (PackageManager.NameNotFoundException e)
{
e.printStackTrace();
}
I need to develop an android application to detect malwares.
I am looking to develop this based on permissions used by all the applications installed. Please let me know how to identify the permissions used by other applications
You can get all installed applications permissions like this.
Get all installed applications
Iterate over the applications
Get each application permissions list
Iterate over the each permission
PackageManager pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo : packages) {
Log.d("test", "App: " + applicationInfo.name + " Package: " + applicationInfo.packageName);
try {
PackageInfo packageInfo = pm.getPackageInfo(applicationInfo.packageName, PackageManager.GET_PERMISSIONS);
//Get Permissions
String[] requestedPermissions = packageInfo.requestedPermissions;
if(requestedPermissions != null) {
for (int i = 0; i < requestedPermissions.length; i++) {
Log.d("test", requestedPermissions[i]);
}
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
You can use this REST API to get details about an app, including permissions required by the app. For instance, to see what permissions WhatsApp is requiring, locate the "permissions" node in the response from this GET request:
http://playstore-api.herokuapp.com/playstore/apps/com.whatsapp
More notes about how to make API calls for this could be found on the GitHub page.