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.
Related
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.
I'm developing an application that needs to know when other third party app requests the microphone.
Is there any way to detect it?
Thanks in advance!
After some research, it seems to be impossible to know when another third party application requests the MICROPHONE due to security reasons.
If you want to perform actions according to actual state of the media recorder, you may have to handle that as explained in this post:
How to detect if MediaRecorder is used by another application?
And about detecting other apps permissions access, I think this can provide an answer: How to detect permission access of other apps?
But if you want to check apps that needs RECORD_AUDIO permission, you can continue reading the following lines:
Based on the answer of Kopi-B at this question
To get the list of apps requesting microphone you can then proceed as follows:
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List pkgAppsList = getPackageManager().queryIntentActivities(mainIntent, 0);
//create a package names list
List<String> packageNames=new ArrayList<>();
for (Object obj : pkgAppsList) {
ResolveInfo resolveInfo = (ResolveInfo) obj;
PackageInfo packageInfo = null;
try {
packageInfo = getPackageManager().getPackageInfo(resolveInfo.activityInfo.packageName, PackageManager.GET_PERMISSIONS);
} catch (PackageManager.NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String[] requestedPermissions = packageInfo.requestedPermissions;
//check the microphone permission
if (requestedPermissions!=null) {
for (String packagePermission : requestedPermissions) {
if (packagePermission == Manifest.permission.RECORD_AUDIO) {
packageNames.add(packageInfo.packageName);
break;
}
}
}
}
I am working on app that is related to security. Application can not be removed even though user reset the device to factory settings. To do this device must be rooted. However, when I tried to obtain the location as root user I am getting this error on Android Jellybean (4.1.1) up
uncaughtException # Exception found!!
java.lang.SecurityException: invalid UID 0
at android.os.Parcel.readException(Parcel.java:1379)
at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:659)
at android.location.LocationManager._requestLocationUpdates(LocationManager.java:664)
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:486)
When i looked into the Android source code, I saw Google has added extra security in LocationManagerService.java here
In requestLocationUpdates function it calls
checkPackageName(Binder.getCallingUid(), packageName);
This is the checkPackageName function
private void checkPackageName(int uid, String packageName) {
if (packageName == null) {
throw new SecurityException("packageName cannot be null");
}
String[] packages = mPackageManager.getPackagesForUid(uid);
if (packages == null) {
throw new SecurityException("invalid UID " + uid);
}
for (String pkg : packages) {
if (packageName.equals(pkg)) return;
}
throw new SecurityException("invalid package name");
}
Any ideas how to get this fixed ? Please advice if you had similar problems how to solve this. Thanks!
Before calling to location service:
final long ident = Binder.clearCallingIdentity();
After calling:
Binder.restoreCallingIdentity(ident);
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.