In case, you ever decide to go with a command-line way, you can try my approach.
Dependencies
- Requires adb to be setup in PC.
Requires busybox binary. If the device is rooted, install Busybox app. Else, download busybox binary from official source, rename the binary to busybox, set Linux compatible executable permission on that binary for everyone and move it into device using
adb push LOCAL_FILE /data/local/tmp/ # LOCAL_FILE is the file path where busybox binary is located in PC
Requires aapt binary. If you're running a CM or its derivative ROM then ignore this requirement. Otherwise, for Android 4.x, you can consider downloading the binary from here, rename the binary to aapt, set Linux compatible executable permission on that binary for everyone and move it into device using
adb push LOCAL_FILE /data/local/tmp/ # LOCAL_FILE is the file path where busybox binary is located in PC .
Android 5.x users: ask Google for assistance.
This is my little script:
#!/system/bin/sh
# Check if the busybox binary exists under /data/local/tmp/ or /system/xbin. Set the detected binary's path into the variable busybox or exit if file doesn't exist or executable permission is not set
[[ -x /data/local/tmp/busybox ]] && busybox=/data/local/tmp/busybox || { [[ -x /system/xbin/busybox ]] && busybox=/system/xbin/busybox || { date +'busybox binary not found or executable permission is not set. Exiting' && exit; }; }
# Check if the aapt binary exists under /data/local/tmp or /system/bin or /system/xbin. Set the detected binary's path into the variable aapt or exit if file doesn't exist or executable permission is not set
[[ -x /data/local/tmp/aapt ]] && aapt=/data/local/tmp/aapt || { [[ -x /system/bin/aapt ]] && aapt=/system/bin/aapt || { [[ -x /system/xbin/aapt ]] && aapt=/system/xbin/aapt || { date +'aapt binary not found or executable permission is not set. Exiting' && exit; }; }; }
! [[ "$1" == +([0-9a-zA-Z._]) ]] && { $busybox printf 'Permission field should not be empty or contain anything beyond these characters: a-zA-Z0-9._' && exit; } || perm=$1;
# List package name of all the installed apps and save them in the file packages.txt under /sdcard
pm list packages | $busybox sed 's/^package://g' | $busybox sort -o /sdcard/packages.txt
$busybox printf "\nList of apps with permission $perm:\n\n";
# From the output we just saved, take each line (package name) and see whether the package has the said permission. Print the app's label and package name when positive. Before printing everything we're also sorting the lines in A-Za-z order. Sorting is not mandatory.
while read line; do
[[ `dumpsys package $line | grep "$perm"` ]] && perm=1 || perm=0;
if [[ $perm == 1 ]]; then
path=$(pm path $line | $busybox sed 's/^package://g');
label=$($aapt d badging $path 2>&1 | $busybox sed -ne '/application: label=/p' | $busybox cut -d "'" -f2);
$busybox printf "$label ($line)\n";
fi
done < /sdcard/packages.txt | sort
Save the script in PC into a file named perm_script.sh
and move it into /sdcard using
adb push LOCAL_FILE /sdcard/ # LOCAL_FILE is the path where you saved that file into PC
Run that file
adb shell sh /sdcard/perm_script.sh PERMISSION # replace PERMISSION with the android permission for which apps are to be shown
The greater the apps installed in the system, the greater the time will be for the command to complete execution. In my device, it took around 40 seconds.
Demo output:
List of apps with permission android.permission.CAMERA:
AirDroid (com.sand.airdroid)
Android Live Wallpapers (com.android.wallpaper)
Barcode Scanner (com.google.zxing.client.android)
Camera (com.android.camera2)
CellConnectionService (com.mediatek.CellConnService)
Chrome (com.android.chrome)
...
Webkey (com.webkey)
YGPS (com.mediatek.ygps)
YouTube (com.google.android.youtube)
One-liner
You can reduce the script to one line:
adb shell pm list packages | tr -d '\r'| sed 's/package://g' | while read line; do [[ `adb shell dumpsys package $line | grep 'android.permission.CAMERA'` ]] && echo "$line"; done
Drawbacks:
- Nothing much, except that you need a *nix OS. Cygwin may work for MS-Windows.
You won't be seeing labels but only the package names.
(To get app's label using its package name, use GAThrawn's answer - works if only the app is available in Play Store; use Izzy's answer - works for any installed app.)
Profit: execution time reduced to ~50%
Bulk removal
Use this command to remove those apps in bulk
adb shell pm list packages | tr -d '\r'| sed 's/package://g' | while read line; do [[ `adb shell dumpsys package $line | grep 'android.permission.CAMERA'` ]] && echo "Removing $line" && adb uninstall $line; done
Expect it to report failure for system apps.
Show App info for all
The following command would display the App info page of the apps having the permission android.permission.CAMERA
adb shell pm list packages | tr -d '\r'| sed 's/package://g' | while read line; do [[ `adb shell dumpsys package $line | grep 'android.permission.CAMERA'` ]] && printf "Launching App info page of $line\n" && adb shell am start -d "package:$line" -n com.android.settings/.applications.InstalledAppDetails --activity-multiple-task && sleep 1.5; done
The flag --activity-multiple-task
is important to note. It is because of that every App info page for an app would be shown as a new task for the same activity. In essence, App Info page for every app having the fed Android permission can be accessed under the Recent activities and once you close the App Info page of an app using the Back button, the App Info page for an other app would show up because they were consecutively opened.
In this way, you can review the app having the Camera permission and take the actions on it, be it Uninstall or Disable.