How to get Category for each App on device on Android?
Solution 1
I know that this is an old post, but for anyone still looking for this, API level 26 (O) has added categories to android.content.pm.ApplicationInfo
.
From the docs https://developer.android.com/reference/android/content/pm/ApplicationInfo#category:
public int category
The category of this app. Categories are used to cluster multiple apps together into meaningful groups, such as when summarizing battery, network, or disk usage. Apps should only define this value when they fit well into one of the specific categories.
Set from the R.attr.appCategory attribute in the manifest. If the manifest doesn't define a category, this value may have been provided by the installer via PackageManager#setApplicationCategoryHint(String, int). Value is
CATEGORY_UNDEFINED
,CATEGORY_GAME
,CATEGORY_AUDIO
,CATEGORY_VIDEO
,CATEGORY_IMAGE
,CATEGORY_SOCIAL
,CATEGORY_NEWS
,CATEGORY_MAPS
, orCATEGORY_PRODUCTIVITY
One can now do something like:
PackageManager pm = context.getPackageManager();
ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int appCategory = applicationInfo.category;
String categoryTitle = (String) ApplicationInfo.getCategoryTitle(context, appCategory)
// ...
}
Solution 2
if you get for each application its package name, you could ask directly to play store which category an app belongs, parsing html response page with this library:
Here's a snippet to solve your problem:
public class MainActivity extends AppCompatActivity {
public final static String GOOGLE_URL = "https://play.google.com/store/apps/details?id=";
public static final String ERROR = "error";
...
private class FetchCategoryTask extends AsyncTask<Void, Void, Void> {
private final String TAG = FetchCategoryTask.class.getSimpleName();
private PackageManager pm;
private ActivityUtil mActivityUtil;
@Override
protected Void doInBackground(Void... errors) {
String category;
pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
Iterator<ApplicationInfo> iterator = packages.iterator();
while (iterator.hasNext()) {
ApplicationInfo packageInfo = iterator.next();
String query_url = GOOGLE_URL + packageInfo.packageName;
Log.i(TAG, query_url);
category = getCategory(query_url);
// store category or do something else
}
return null;
}
private String getCategory(String query_url) {
boolean network = mActivityUtil.isNetworkAvailable();
if (!network) {
//manage connectivity lost
return ERROR;
} else {
try {
Document doc = Jsoup.connect(query_url).get();
Element link = doc.select("span[itemprop=genre]").first();
return link.text();
} catch (Exception e) {
return ERROR;
}
}
}
}
}
You could make these queries in an AsyncTask, or in a service. Hope that you find it helpful.
Solution 3
Any suggestions on how to get the Category of the App?
Apps don't have categories. Some markets have categories.
From what I can tell there is nothing related to Category stored on the device itself.
Correct.
I was thinking of using the android market API to search for the application in the market and use the Category value returned by the search.
At the present time, there is no "android market API", unless you have a good legal team and a significant legal defense fund.
Moreover, not all apps are distributed via the "android market", particularly on devices like the Kindle Fire. Also, developers are welcome to change categories whenever they wish, at least on the Google Play Store.
Any suggestions on how best to do this?
Drop the feature and move on to other ways to add value.
Solution 4
I also faced the same issue. The solution for the above query is stated below.
Firstly, download the Jsoup
library or download the jar file.
or
Add this to your build.gradle
(Module: app) implementation 'org.jsoup:jsoup:1.11.3'
private class FetchCategoryTask extends AsyncTask<Void, Void, Void> {
private final String TAG = FetchCategoryTask.class.getSimpleName();
private PackageManager pm;
//private ActivityUtil mActivityUtil;
@Override
protected Void doInBackground(Void... errors) {
String category;
pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
Iterator<ApplicationInfo> iterator = packages.iterator();
// while (iterator.hasNext()) {
// ApplicationInfo packageInfo = iterator.next();
String query_url = "https://play.google.com/store/apps/details?id=com.imo.android.imoim"; //GOOGLE_URL + packageInfo.packageName;
Log.i(TAG, query_url);
category = getCategory(query_url);
Log.e("CATEGORY", category);
// store category or do something else
//}
return null;
}
private String getCategory(String query_url) {
try {
Document doc = Jsoup.connect(query_url).get();
Elements link = doc.select("a[class=\"hrTbp R8zArc\"]");
return link.text();
} catch (Exception e) {
Log.e("DOc", e.toString());
}
}
}
In return, you will get Application Company Name and category of the application
Solution 5
I made a Kotlin solution based on the answer from @Ankit Kumar Singh.
This solution maps the category to an enum, in case you want to do other things than just show it.
import kotlinx.coroutines.*
import org.jsoup.Jsoup
import javax.inject.Inject
import javax.inject.Singleton
class AppCategoryService {
companion object {
private const val APP_URL = "https://play.google.com/store/apps/details?id="
private const val CAT_SIZE = 9
private const val CATEGORY_STRING = "category/"
}
suspend fun fetchCategory(packageName: String): AppCategory {
val url = "$APP_URL$packageName&hl=en" //https://play.google.com/store/apps/details?id=com.example.app&hl=en
val categoryRaw = parseAndExtractCategory(url) ?: return AppCategory.OTHER
return AppCategory.fromCategoryName(categoryRaw)
}
@Suppress("BlockingMethodInNonBlockingContext")
private suspend fun parseAndExtractCategory(url: String): String? = withContext(Dispatchers.IO) {
return@withContext try {
val text = Jsoup.connect(url).get()?.select("a[itemprop=genre]") ?: return@withContext null
val href = text.attr("abs:href")
if (href != null && href.length > 4 && href.contains(CATEGORY_STRING)) {
getCategoryTypeByHref(href)
} else {
null
}
} catch (e: Throwable) {
null
}
}
private fun getCategoryTypeByHref(href: String) = href.substring(href.indexOf(CATEGORY_STRING) + CAT_SIZE, href.length)
}
And here is the enum with all the possible values at of this moment in time:
// Note: Enum name matches API value and should not be changed
enum class AppCategory {
OTHER,
ART_AND_DESIGN,
AUTO_AND_VEHICLES,
BEAUTY,
BOOKS_AND_REFERENCE,
BUSINESS,
COMICS,
COMMUNICATION,
DATING,
EDUCATION,
ENTERTAINMENT,
EVENTS,
FINANCE,
FOOD_AND_DRINK,
HEALTH_AND_FITNESS,
HOUSE_AND_HOME,
LIBRARIES_AND_DEMO,
LIFESTYLE,
MAPS_AND_NAVIGATION,
MEDICAL,
MUSIC_AND_AUDIO,
NEWS_AND_MAGAZINES,
PARENTING,
PERSONALIZATION,
PHOTOGRAPHY,
PRODUCTIVITY,
SHOPPING,
SOCIAL,
SPORTS,
TOOLS,
TRAVEL_AND_LOCAL,
VIDEO_PLAYERS,
WEATHER,
GAMES;
companion object {
private val map = values().associateBy(AppCategory::name)
private const val CATEGORY_GAME_STRING = "GAME_" // All games start with this prefix
fun fromCategoryName(name: String): AppCategory {
if (name.contains(CATEGORY_GAME_STRING)) return GAMES
return map[name.toUpperCase(Locale.ROOT)] ?: OTHER
}
}
}
![Mike Cooper](https://i.stack.imgur.com/uKeq4.png?s=256&g=1)
Mike Cooper
Mike Cooper is Founder and CEO at Revocent Inc (www.revocent.com). Revocent specializes in Certificate Automation software for enterprises of all sizes.
Updated on June 24, 2022Comments
-
Mike Cooper about 2 years
I've got an Android app which scans for all Apps installed on the device and then reports this to a server (it's an MDM agent). Any suggestions on how to get the Category of the App? Everyone has a different list of Categories, but basically something like Game, Entertainment, Tools/Utilities, etc.
From what I can tell there is nothing related to Category stored on the device itself. I was thinking of using the android market API to search for the application in the market and use the Category value returned by the search. Not sure how successful this will be finding a match. Any suggestions on how best to do this?
Any suggestions on a different approach?
Thanks in advance. mike
-
Bhanu Sharma about 8 yearshey Dr. booster do this. They categorized all game and show in grid view. Clean master also do same have u any idea how they did this and one thing i off internet but they did the same that means they do something which doesn't require internet or any API
-
Tomas Maksimavicius over 6 yearsHey, it works well, but what if google play is in other language? How to get only english version of category?
-
soufien karray over 6 yearstry to add "&&hl=en" to query_url ;)
-
Jayesh M about 6 yearsI tried this code and it always returning error. Is there anything I want to do apart from this code ?
-
Makvin about 5 yearsfrom above solution i got both company name and category name but Is it possible to find its a game or app?
-
Rishabh Chandaliya Jain almost 5 years@Makvin yes you can find whether it is an game or application. Games also have sub-category list it down(eg. Action, Adventure, Arcade,etc). if my application category is same as Action or Adventure or Arcade I'll assign it as a GAME It's a work around but this might help you discover whether application is game or not Thansk
-
android developer almost 5 yearsWill this work even today? Will it always be in English? Is there a way to get all possible categories? In case things change, how did you find what to put as parameter for
doc.select()
?