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
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.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import net.nrask.appsanywhere.deviceSettings.installedApps.database.AppCategory
import org.jsoup.Jsoup
object GetAppCategoryService {
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/"
private const val CATEGORY_GAME_STRING = "GAME_" // All games start with this prefix
private const val DEFAULT_VALUE = "OTHERS"
fun fetchCategory(packageName: String, onResult: (AppCategory) -> Unit) {
val url = "$APP_URL$packageName&hl=en" //https://play.google.com/store/apps/details?id=com.example.app&hl=en
val categoryRaw = parseAndExtractCategory(url)
launch(UI) {
onResult(AppCategory.fromCategoryName(categoryRaw ?: DEFAULT_VALUE))
}
}
private fun parseAndExtractCategory(url: String): String? {
return try {
val text = Jsoup.connect(url).get()?.select("a[itemprop=genre]") ?: return null
val href = text.attr("abs:href")
if (href != null && href.length > 4 && href.contains(CATEGORY_STRING)) {
getCategoryTypeByHref(href)
} else {
null
}
} catch (e: kotlin.Exception) {
//TODO handle error
null
}
}
private fun getCategoryTypeByHref(href: String): String? {
val appCategoryType = href.substring(href.indexOf(CATEGORY_STRING) + CAT_SIZE, href.length)
return if (appCategoryType.contains(CATEGORY_GAME_STRING)) {
AppCategory.GENERAL_GAMES_CATEGORY_NAME
} else appCategoryType
}
}
And here is the enum with all the possible values at of this moment in time:
// Int value is equal to the category's name's hashvalue - For easy parsing
enum class AppCategory(val rawValue: Int) {
OTHER(0),
ART_AND_DESIGN(1798113474),
AUTO_AND_VEHICLES(-201031457),
BEAUTY(1955267708),
BOOKS_AND_REFERENCE(652448174),
BUSINESS(-364204096),
COMICS(1993477496),
COMMUNICATION(2080958390),
DATING(2009386219),
EDUCATION(-1799129208),
ENTERTAINMENT(-678717592),
EVENTS(2056967449),
FINANCE(-135275590),
FOOD_AND_DRINK(-267698865),
HEALTH_AND_FITNESS(704829917),
HOUSE_AND_HOME(-908401466),
LIBRARIES_AND_DEMO(-1893543311),
LIFESTYLE(-1796047851),
MAPS_AND_NAVIGATION(1381037124),
MEDICAL(1658758769),
MUSIC_AND_AUDIO(702385524),
NEWS_AND_MAGAZINES(1916976715),
PARENTING(561964760),
PERSONALIZATION(1779216900),
PHOTOGRAPHY(-470332035),
PRODUCTIVITY(-953829166),
SHOPPING(438165864),
SOCIAL(-1843721363),
SPORTS(-1842431105),
TOOLS(80007611),
TRAVEL_AND_LOCAL(856995806),
VIDEO_PLAYERS(289768878),
WEATHER(1941423060),
GAMES("GAMES".hashCode());
companion object {
private val map = AppCategory.values().associateBy(AppCategory::rawValue)
const val GENERAL_GAMES_CATEGORY_NAME = "GAMES"
fun fromCategoryName(name: String): AppCategory {
return map[name.hashCode()] ?: AppCategory.OTHER
}
}
}