I'm targeting my app to support 30 (R).
I've notice that some apps are missing to choose when calling this:
baseActivity.startActivity(Intent(MediaStore.ACTION_IMAGE_CAPTURE))
When targeting to 29, this code shows several apps to choose before taking the picture:
Native camera app
B612 Camera app
After targeting to 30, the camera app is being opened directly (no option to choose).
I looked in the android 11 changes but didn't see anything special.
Is there anything that needs to be change in my side?
Thanks for reading/helping
Once your targetSdkVersion reaches 30, ACTION_IMAGE_CAPTURE will only display pre-installed camera apps, not user-installed apps.
I've found a workaround;
TL;DR: Read the AndroidManifest.xml's of the apps yourself to find the camera apps.
Note: This may result in your app being banned from the store.
Step 1:
Using the PackageManager, create a list of all apps that have the Camera-permission granted.
public static List<PackageInfo> getPackageInfosWithCameraPermission(Context context){
//Get a list of compatible apps
PackageManager pm = context.getPackageManager();
List<PackageInfo> installedPackages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS);
ArrayList<PackageInfo> cameraPermissionPackages = new ArrayList<PackageInfo>();
//filter out only camera apps
for (PackageInfo somePackage : installedPackages) {
//- A camera app should have the Camera permission
boolean hasCameraPermission = false;
if (somePackage.requestedPermissions == null || somePackage.requestedPermissions.length == 0) {
continue;
}
for (String requestPermission : somePackage.requestedPermissions) {
if (requestPermission.equals(Manifest.permission.CAMERA)) {
//Ask for Camera permission, now see if it's granted.
if (pm.checkPermission(Manifest.permission.CAMERA, somePackage.packageName) == PackageManager.PERMISSION_GRANTED) {
hasCameraPermission = true;
break;
}
}
}
if (hasCameraPermission) {
cameraPermissionPackages.add(somePackage);
}
}
return cameraPermissionPackages;
}
Step 2: Get the AndroidManifest from the APK-file (from PackageInfo)
public static Document readAndroidManifestFromPackageInfo(PackageInfo packageInfo) {
File publicSourceDir = new File(packageInfo.applicationInfo.publicSourceDir);
//Get AndroidManifest.xml from APK
ZipFile apkZipFile = new ZipFile(apkFile, ZipFile.OPEN_READ);
ZipEntry manifestEntry = apkZipFile.getEntry("AndroidManifest.xml");
InputStream manifestInputStream = apkZipFile.getInputStream(manifestEntry);
try {
Document doc = new CompressedXmlParser().parseDOM(manifestInputStream);
return doc;
} catch (Exception e) {
throw new IOException("Error reading AndroidManifest", e);
}
}
Step 3: Read the AndroidManifest to find the Activities with the correct IntentFilter(s)
public static List<ComponentName> getCameraComponentNamesFromDocument(Document doc) {
#SuppressLint("InlinedApi")
String[] correctActions = {MediaStore.ACTION_IMAGE_CAPTURE, MediaStore.ACTION_IMAGE_CAPTURE_SECURE, MediaStore.ACTION_VIDEO_CAPTURE};
ArrayList<ComponentName> componentNames = new ArrayList<ComponentName>();
Element manifestElement = (Element) doc.getElementsByTagName("manifest").item(0);
String packageName = manifestElement.getAttribute("package");
Element applicationElement = (Element) manifestElement.getElementsByTagName("application").item(0);
NodeList activities = applicationElement.getElementsByTagName("activity");
for (int i = 0; i < activities.getLength(); i++) {
Element activityElement = (Element) activities.item(i);
String activityName = activityElement.getAttribute("android:name");
NodeList intentFiltersList = activityElement.getElementsByTagName("intent-filter");
for (int j = 0; j < intentFiltersList.getLength(); j++) {
Element intentFilterElement = (Element) intentFiltersList.item(j);
NodeList actionsList = intentFilterElement.getElementsByTagName("action");
for (int k = 0; k < actionsList.getLength(); k++) {
Element actionElement = (Element) actionsList.item(k);
String actionName = actionElement.getAttribute("android:name");
for (String correctAction : correctActions) {
if (actionName.equals(correctAction)) {
//this activity has an intent filter with a correct action, add this to the list.
componentNames.add(new ComponentName(packageName, activityName));
}
}
}
}
}
return componentNames;
}
Step 4: Create a list of all Camera Apps
List<> cameraApps = new ArrayList<>();
for (PackageInfo somePackage : cameraPermissionPackages) {
Document doc = readAndroidManifestFromPackageInfo(somePackage);
List<ComponentName> componentNames = getCameraComponentNamesFromDocument(doc);
if (componentNames.size() == 0) {
continue; //This is not a Camera app
}
cameraApps.add(cameraApp);
}
Step 5: Present list of Camera Apps to the user.
Just create a dialog or something.
I've worked it out into a library:
https://github.com/frankkienl/Camera11
Related
For force update I used to call the app url and check the for the html tag value <softwareVersion><softwareVersion/> but suddenly it stopped working there is no softwareVersion tag in the page so getting null. Is there any google api available to check the google play app version.
Update -
I investigate in more details when I used to call the url the response was 200 but now I am getting 405
I come up with a solution. When ever I am pushing a new version in the playstore I will add the version in the what's new, like this -
WHAT'S NEW
Version - 2.11.0
- New changes 1
- New changes 2
And I look for this Version -
So Full code looks like this -
class VersionCheckTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String mVer = "";
String mData = "";
try {
URL mUrl = new URL(urls[0]);
BufferedReader in = new BufferedReader(new InputStreamReader(mUrl.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null){
if (inputLine == null)
break;
mData += inputLine;
}
in.close();
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
/*
* we are looking for this tag <div itemprop="description"><content>Version - 2.11.0<br>
* We need to make sure every time we release a new version we should add the line in what's new -
*
* Version - 2.11.1
*
* - New changes 1
* - New changes 2
*/
String startToken = "Version - ";
String endToken = "<";
int index = mData.indexOf(startToken);
if (index == -1) {
mVer = null;
} else {
mVer = mData.substring(index + startToken.length(), index
+ startToken.length() + 100);
mVer = mVer.substring(0, mVer.indexOf(endToken)).trim();
}
return mVer;
}
protected void onPostExecute(String store_version) {
String currentVersion = "";
try {
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
currentVersion = pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
Log.v(TAG, "Recv NameNotFoundException. Msg:" + e.getMessage());
}
Log.d(TAG, "store_version: " + store_version);
Log.d(TAG, "device_version: " + currentVersion);
if (store_version != null) {
if (versionCompare(store_version, currentVersion) > 0) {
dialog.setMessage(String.format(getResources().getString(R.string.update_message), getResources().getString(R.string.app_name), store_version));
dialog.show();
} else {
showDisclaimer();
}
}
}
}
public int versionCompare(String storeVersion, String currentVersion) {
String[] vals1 = storeVersion.split("\\.");
String[] vals2 = currentVersion.split("\\.");
int i = 0;
// set index to first non-equal ordinal or length of shortest version string
while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
i++;
}
// compare first non-equal ordinal number
if (i < vals1.length && i < vals2.length) {
int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
return Integer.signum(diff);
}
// the strings are equal or one string is a substring of the other
// e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4"
return Integer.signum(vals1.length - vals2.length);
}
Maybe, at the end of march, Google changed Play store's HTML Code.
The structure of additional information has also changed.
Some developers, including me, use Jsoup to check for the latest version in the Play Store.
Perhaps you were using code like this:
Document doc = Jsoup.connect
("https://play.google.com/store/apps/details?id=name.package.your").get();
Elements Version = doc.select(".content");
for (Element v : Version) {
if (v.attr("itemprop").equals("softwareVersion")) {
VersionMarket = v.text();
}
}
but, after play store's change, your code return null.
because, "itemprop" and "sofrwareVersion" is gone, like that.
enter image description here
So, you need a new way to parse the version of your app in Google Play store's ADDITION INFORMATION with Jsoup.
try {
Document doc = Jsoup
.connect(
"https://play.google.com/store/apps/details?id=name.package.your")
.get();
Elements Version = doc.select(".htlgb ");
for (int i = 0; i < 5 ; i++) {
VersionMarket = Version.get(i).text();
if (Pattern.matches("^[0-9]{1}.[0-9]{1}.[0-9]{1}$", VersionMarket)) {
break;
}
}
The above code works as follows.
Parsing play store's your app page.
Selecting all "htlgb" contents.
like in image, "3 March 2018", "1,000+" "2.0.4", "4.4 and up, etc."
In [for Loop], [Regex] finds a value matching your version pattern (like 2.0.4) and stops.
VersionMarket is your "app version" and you can use it.
//2018-08-04 Add Comment
For some reason, the code above returns information about "Installs" instead of "version information".
Therefore, if you modify the code as shown below, you can return "version information" again.
try {
Document doc = Jsoup
.connect(
"https://play.google.com/store/apps/details?id=name.package.your")
.get();
Elements Version = doc.select(".htlgb ");
for (int i = 0; i < 10 ; i++) {
VersionMarket = Version.get(i).text();
if (Pattern.matches("^[0-9]{1}.[0-9]{1}.[0-9]{1}$", VersionMarket)) {
break;
}
}
The above code changed the number in "for break" from 5 to 10.
Because the number of "htlgb" codes has changed in Google Play Store's HTML Code.
No, no API exists for checking your app version on Play. Instead, you could implement a solution using Firebase Remote Config, then you have much more control over the minimum version your users see.
What I do
I'm retrieving a list of all installed apps like following (for a launcher like app):
PackageManager pm = context.getPackageManager();
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null)
.addCategory(Intent.CATEGORY_LAUNCHER);
// flag PackageManager.GET_RESOLVED_FILTER will set ResolveInfo.filter (not documented, but tested)
// many examples use flag == 0, but then the filter is always null
List<ResolveInfo> ril = pm.queryIntentActivities(mainIntent, PackageManager.GET_RESOLVED_FILTER);
if (ril != null) {
for (ResolveInfo ri : ril) {
// I need this info!
// ri.isDefault is always false...
boolean isDefault = ri.isDefault || ril.filter.hasCategory(Intent.CATEGORY_DEFAULT);
}
}
So far, this works. But some apps like samsungs phone app do not respect that they should only flag one activity with Intent.CATEGORY_DEFAULT. Here's what the categories for the two activities in samsung's app look like:
ActivityInfo{cd007eb com.android.contacts.activities.PeopleActivity}
filter:
0 = "android.intent.category.DEFAULT"
1 = "android.intent.category.LAUNCHER"
2 = "android.intent.category.BROWSABLE"
3 = "android.intent.category.APP_CONTACTS"
ActivityInfo{3e9ba8d com.android.dialer.DialtactsActivity}
filter:
0 = "android.intent.category.DEFAULT"
1 = "android.intent.category.LAUNCHER"
2 = "android.intent.category.BROWSABLE"
Requirements
I need a list of all activities a launcher like app like mine can launch
I need the info if a ResolveInfo is the one that is launched if I use the apps package name only like if I use the intent retrieved by following command: pm.getLaunchIntentForPackage(packageName). This one is what I call the default launch intent in this post
Question
How can I find out reliably if a ResolveInfo belongs to the default launch intent?
You can use the queryIntentActivities as follows:
PackageManager pm = context.getPackageManager();
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null)
.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> ril = pm.queryIntentActivities(mainIntent, PackageManager.MATCH_DEFAULT_ONLY);
Based on the documentation for MATCH_DEFAULT_ONLY:
Resolution and querying flag: if set, only filters that support the
CATEGORY_DEFAULT will be considered for matching. This is a synonym
for including the CATEGORY_DEFAULT in your supplied Intent.
SOLUTION
This solution is useable as long as you assume that only some apps register multiple default activities.
get all ResolveInfos like in my question
create a HashMap and insert package names and number of entries in list
use the HashMap to determine if you even need to check if the ResolveInfo belongs to the default activity or not
if you need to check, make the slow check for this ResolveInfo
Code
List<ResolveInfo> ril = ...;
HashMap<String, Integer> packageCountMap = getPackageCountMap(uniqueRil);
for (ResolveInfo ri :: ril) {
boolean isDefault = isDefaultIntentForPhoneApp(packageCountMap, ri);
// use this info...
}
Helper function:
public static HashMap<String, Integer> getPackageCountMap(List<ResolveInfo> ril) {
HashMap<String, Integer> map = new HashMap<>();
ResolveInfo ri;
Integer count;
if (ril != null) {
for (int i = 0; i < ril.size(); i++) {
ri = ril.get(i);
count = map.get(ri.activityInfo.packageName);
if (count == null) {
count = 1;
} else {
count++;
}
map.put(ri.activityInfo.packageName, count);
}
}
return map;
}
public static boolean isDefaultIntentForPhoneApp(PackageManager pm, HashMap<String, Integer> packageCountMap, ResolveInfo ri) {
boolean isDefault;
// count how often the package name exists => 1x => then the activity must be the default one, no need to do any check
Integer count = packageCountMap.get(ri.activityInfo.packageName);
if (count == null || count <= 1) {
isDefault = true;
}
// otherwise get default activity and compare it
else {
Intent i = pm.getLaunchIntentForPackage(packageName);
ComponentName cn = i.resolveActivity(pm);
isDefault = cn != null && cn.getClassName().equals(ri.activityInfo.name);
}
return isDefault;
}
In my app I need to monitorize recently added or updated packages, but since Oreo this is a hard task.
To do it I have a service that runs every X time to detect the new installed/updated apps.
The main core of this service is to call the getChangedPackages function from the PackageManager, but this function always returns null, even if I install or update any app from or not from the Play Store in the interval between two consequtive calls to getChangedPackages.
https://developer.android.com/reference/android/content/pm/PackageManager.html#getChangedPackages(int)
I need to request any permission to call this function? Is the getChangedPackages buggy?
private void _doProcess()
{
try
{
PackageManager package_manager = getPackageManager();
int sequence_number = ApplicationPreferences.getInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, 0);
ChangedPackages changed_packages = package_manager.getChangedPackages(sequence_number);
LogUtilities.show(this, String.format("Retrieve recently apps installs/updates using sequence number %d returns %s", sequence_number, changed_packages == null ? "null" : "a not null object"));
if (changed_packages == null) changed_packages = package_manager.getChangedPackages(0);
LogUtilities.show(this, String.format("Retrieve recently apps installs/updates using sequence number %d returns %s", sequence_number, changed_packages == null ? "null" : "a not null object"));
if (changed_packages != null)
{
List<String> packages_names = changed_packages.getPackageNames();
LogUtilities.show(this, String.format("%d recently installed/updated apps", packages_names == null ? 0 : packages_names.size()));
if (packages_names != null) for (String package_name : packages_names) PackagesUpdatedReceiver.doProcessPackageUpdate(this, new Intent(isNewInstall(package_manager, package_name) ? Intent.ACTION_PACKAGE_ADDED : Intent.ACTION_PACKAGE_REPLACED).setData(Uri.parse(String.format("package:%s", package_name))));
LogUtilities.show(this, String.format("Storing %s is the sequence number for next iteration", changed_packages.getSequenceNumber()));
ApplicationPreferences.putInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, changed_packages.getSequenceNumber());
}
else
{
LogUtilities.show(this, String.format("Storing %s is the sequence number for next iteration", sequence_number + 1));
ApplicationPreferences.putInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, sequence_number + 1);
}
}
catch (Exception e)
{
LogUtilities.show(this, e);
}
}
My experimental results so far have shown that this PackageManager API method getChangedPackages() is not reliable: quite often the returned ChangedPackages value contains many unchanged packages. So I’ve decided to implement a similar feature in a class called PackageUtils, as shown below. The idea is to poll for all the installed packages, as shown in method getInstalledPackageNames() below, and compare the string list with a previously saved one. This comparison boils down to comparing 2 string lists, as shown in method operate2StringLists() below. To get a set of removed packages, use GET_1_MINUS_2_OR_REMOVED as operation. To get a set of added packages, use GET_2_MINUS_1_OR_ADDED as operation.
public class PackageUtils {
public static final int GET_1_MINUS_2_OR_REMOVED = 0;
public static final int GET_2_MINUS_1_OR_ADDED = 1;
// Get all the installed package names
public static List<String> getInstalledPackageNames(Context context) {
List<String> installedPackageNames = new ArrayList<>();
try {
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> appInfoList = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo appInfo : appInfoList) {
installedPackageNames.add(appInfo.packageName);
}
} catch (Exception e) {
e.printStackTrace();
}
return installedPackageNames;
}
// Compare 2 string lists and return differences.
public static Set<String> operate2StringLists(List<String> pkgList1, List<String> pkgList2, int operation) {
Set<String> result = null;
Set<String> pkgSet1 = new HashSet<String>(pkgList1);
Set<String> pkgSet2 = new HashSet<String>(pkgList2);
switch (operation) {
case GET_1_MINUS_2_OR_REMOVED:
pkgSet1.removeAll(pkgSet2);
result = pkgSet1;
break;
case GET_2_MINUS_1_OR_ADDED:
pkgSet2.removeAll(pkgSet1);
result = pkgSet2;
break;
default:
break;
}
return result;
}
}
The code has been tested on an Android Oreo device. It can reliably detect all added and removed packages between 2 time instances. However, it can’t detect updated packages in-between.
Finally got it. You have to create a variable called sequenceNumber, and update it every time you query changed packages.
private static int sequenceNumber = 0;
...
PackageManager pm = getContext().getPackageManager();
ChangedPackages changedPackages = pm.getChangedPackages(sequenceNumber);
if(changedPackages != null)
sequenceNumber = changedPackages.getSequenceNumber();
I know that via the Account Manager I can access to the list of the accounts on the device.
Account[] accounts = AccountManager.get(this).getAccounts();
I know as well that using the android.settings.ACCOUNT_SYNC_SETTINGS I can open the Sync Settings for a specific account
Intent in=new Intent("android.settings.ACCOUNT_SYNC_SETTINGS");
in.putExtra("account", accounts[3]);
What I would like to do is to open the "Account Settings" for a specific account, like this:
And not like this:
General Approach:
The tricky part is that Android's definition of Account is pretty abstract, so depending on your use case you'll encounter accounts without these screens, or with multiple screens. These screens may not look like Preferences/Settings screens at all - they could be any Activity as defined by the Account authenticator.
Generally though, I think this is what you could do:
Use the getAuthenticatorTypes() method of AccountManager. This
will give you all of the AuthenticatorDescriptions. Depending on
your use case, you can pick the AuthenticatorDescription you care
about (based on the "type" value) and just further investigate that.
http://developer.android.com/reference/android/accounts/AccountManager.html#getAuthenticatorTypes()
The AuthenticatorDescription will tell you the
accountPreferencesId that defines the "hierarchy of
PreferenceScreen to be added to the settings page for the account".
Which in turn defines a "PreferenceScreen xml hierarchy that
contains a list of PreferenceScreens that can be invoked to manage
the authenticator".
http://developer.android.com/reference/android/accounts/AuthenticatorDescription.html
Use the accountPreferencesId and the package provided by the
AuthenticatorDescription to parse the Intents you need, allowing you
to navigate your user to them. Reference for what the XML will look
like:
http://developer.android.com/reference/android/accounts/AbstractAccountAuthenticator.html
tl;dr - the code:
Here's a method that finds the Activity action/class and starts it. It doesn't account for the fact that there may be multiple Activities defined in the Preferences XML referenced above. In fact, it doesn't account for a lot of error scenarios and can surely be optimized, but should serve as a decent proof of concept and starting point:
//somewhere in your app call this
//com.android.email works to open the email preferences on my Galaxy s4
startPreferenceActivity("com.android.email");
private void startPreferenceActivity(String type) {
AccountManager accountManager = AccountManager.get(this);
AuthenticatorDescription[] descriptions = accountManager.getAuthenticatorTypes();
AuthenticatorDescription neededDescription = null;
for (AuthenticatorDescription description : descriptions) {
if (description.type.contains(type)) {
neededDescription = description;
break;
}
}
if (neededDescription != null) {
String packageName = neededDescription.packageName;
int prefsId = neededDescription.accountPreferencesId;
try {
Resources resources = getPackageManager().getResourcesForApplication(packageName);
XmlResourceParser xpp = resources.getLayout(prefsId);
xpp.next();
String action = null;
String targetPackage = packageName; //default to the account pref package name...?
String targetClass = null;
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if (xpp.getName().equals("intent")) {
int count = xpp.getAttributeCount();
for (int i = 0; i < count; i++) {
String name = xpp.getAttributeName(i);
if (name.equals("action")) {
action = xpp.getAttributeValue(i);
} else if (name.equals("targetPackage")) {
targetPackage = xpp.getAttributeValue(i);
} else if (name.equals("targetClass")) {
targetClass = xpp.getAttributeValue(i);
}
}
}
}
eventType = xpp.next();
}
if (action != null) {
startActivity(new Intent(action));
} else if (targetClass != null) {
startActivity(new Intent(createPackageContext(targetPackage, Context.CONTEXT_IGNORE_SECURITY), Class.forName(targetClass)));
}
} catch (PackageManager.NameNotFoundException e) {
} catch (Exception e) {
}
}
}
You may have database of your accounts info u can open it and design a similar style form for it this can solve your problem
I have to determine list of permission used each by the installed application on my device.
I have got the list of applications installed and there package name using the following code:
PackageManager pm = this.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> list = m.queryIntentActivities(intent,PackageManager.PERMISSION_GRANTED);
for (ResolveInfo rInfo : list) {
Log.d("Installed Applications", rInfo.activityInfo.applicationInfo
.loadLabel(pm).toString());
Log.d("packegename",rInfo.activityInfo.applicationInfo.packageName.
toString());
}
How do I get permission used by each application?
So i coded it.i needed not just the permissions but also the recievers and services.pls see the following code,hope its useful for others.
PackageManager p = this.getPackageManager();
final List <PackageInfo> appinstall=p.getInstalledPackages(PackageManager.GET_PERMISSIONS|PackageManager.GET_RECEIVERS|
PackageManager.GET_SERVICES|PackageManager.GET_PROVIDERS);
for(PackageInfo pInfo:appinstall){
//PermissionInfo[] permission=pInfo.permissions;
String[] reqPermission=pInfo.requestedPermissions;
ServiceInfo[] services=pInfo.services;
ProviderInfo[] providers=pInfo.providers;
int versionCode=pInfo.versionCode;
Log.d("versionCode-package ",Integer.toString(versionCode));
Log.d("Installed Applications", pInfo.applicationInfo
.loadLabel(pm).toString());
Log.d("packegename",pInfo.packageName.
toString());
if(reqPermission!=null)
for(int i=0;i<reqPermission.length;i++)
Log.d("permission list",reqPermission[i]);
}
NOTICE-setting flags is important otherwise it causes problem n u cnt get services ,provider
NOTE- NULL CHECK IS IMP OR IT GIVES NPE
also the previous code i wrote ws using activityInfo this one uses packageInfo .it better now i guess :)
happy coding ppl :)
Here how to retrieve the list of the apps installed on an Android device, and the permissions used by every app.
private static final String TAG = "MyActivity";
...
final PackageManager pm = getPackageManager();
final List<ApplicationInfo> installedApps = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for ( ApplicationInfo app : installedApps ) {
//Details:
Log.d(TAG, "Package: " + app.packageName);
Log.d(TAG, "UID: " + app.uid);
Log.d(TAG, "Directory: " + app.sourceDir);
//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");
}
Log.d(TAG, "Permissions: " + permissions);
}
}
catch ( PackageManager.NameNotFoundException e ) {
e.printStackTrace();
}
}
Check out freetaskmanager
// Loop through all installed packaged to get a list of used permissions and PackageInfos
for (PackageInfo pi : appList) {
// Do not add System Packages
if ((pi.requestedPermissions == null || pi.packageName.equals("android")) ||
(pi.applicationInfo != null && (pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0))
continue;
for (String permission : pi.requestedPermissions) {
Map<String, String> curChildMap = new HashMap<String, String>();
try {
PermissionInfo pinfo = mPm.getPermissionInfo(permission, PackageManager.GET_META_DATA);
CharSequence label = pinfo.loadLabel(mPm);
CharSequence desc = pinfo.loadDescription(mPm);
} catch (NameNotFoundException e) {
Log.i(TAG, "Ignoring unknown permission " + permission);
continue;
}
}
}
This is the only thing I found, though I've not tested it out.
Let me know if it works for any one:
pm.getPackageInfo(rInfo.activityInfo.applicationInfo.packageName, packageManager.GET_PERMISSIONS);