Mik*_*per 6 android google-play
我有一个Android应用程序,它扫描设备上安装的所有应用程序,然后将其报告给服务器(它是MDM代理).有关如何获得应用类别的任何建议?每个人都有不同的类别列表,但基本上类似于游戏,娱乐,工具/实用程序等.
据我所知,与设备本身存储的类别无关.我正在考虑使用Android市场API来搜索市场中的应用程序并使用搜索返回的Category值.不确定这会找到一场比赛有多成功.有关如何最好地做到这一点的任何建议?
有关不同方法的任何建议吗?
提前致谢.麦克风
小智 13
我知道这是一篇旧文章,但对于仍在寻找此内容的人来说,API 级别 26 (O) 已将类别添加到android.content.pm.ApplicationInfo.
来自文档https://developer.android.com/reference/android/content/pm/ApplicationInfo#category:
public int category该应用程序的类别。类别用于将多个应用程序聚集到有意义的组中,例如在汇总电池、网络或磁盘使用情况时。应用程序仅应在非常适合某一特定类别时才定义此值。
从清单中的R.attr.appCategory属性设置。如果清单未定义类别,则安装程序可能已通过PackageManager#setApplicationCategoryHint(String, int)提供此值。值为
CATEGORY_UNDEFINED,CATEGORY_GAME,CATEGORY_AUDIO,CATEGORY_VIDEO,CATEGORY_IMAGE,CATEGORY_SOCIAL,CATEGORY_NEWS,CATEGORY_MAPS, 或CATEGORY_PRODUCTIVITY
现在可以做类似的事情:
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)
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果为每个应用程序获取其程序包名称,则可以直接要求商店播放应用程序所属的类别,并使用以下库解析html响应页面:
以下是解决您的问题的代码段:
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;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在AsyncTask或服务中进行这些查询。希望对您有所帮助。
有关如何获得应用类别的任何建议?
应用没有类别.一些市场有类别.
据我所知,与设备本身存储的类别无关.
正确.
我正在考虑使用Android市场API来搜索市场中的应用程序并使用搜索返回的Category值.
目前,没有"Android市场API",除非你有一个良好的法律团队和重要的法律辩护基金.
此外,并非所有应用程序都通过"Android市场"分发,特别是在Kindle Fire等设备上.此外,欢迎开发人员随时更改类别,至少在Google Play商店中如此.
有关如何最好地做到这一点的任何建议?
删除该功能并继续使用其他方式来增加价值.
我根据 @Ankit Kumar Singh 的答案制作了一个 Kotlin 解决方案。
此解决方案将类别映射到枚举,以防您想做其他事情而不仅仅是显示它。
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)
}
Run Code Online (Sandbox Code Playgroud)
这是此时此刻所有可能值的枚举:
// 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
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6549 次 |
| 最近记录: |