Android: Determine category of installed apps - android

Given the list of installed packages on an Android device, is there a way to sort the applications into categories without using a self-compiled hard-coded list of apps in categories?
For example, if the installed apps were Phone, Angry Birds & Messages, Phone & Messages might be in Communications and Angry Birds in Games.
I've seen How to get Category for each App on device on Android? yet hoped there may be a method that has come along since.

No, because apps don't have categories. Apps don't need to be installed through google play, the categories on other stores won't be the same. It may never have been installed from a store to begin with- I sideload apps all the time written by myself or friends. Th concept doesn't exist.
Not to mention Google Play categories are pretty bad- things frequently don't fall into one or the other, the descriptions are vague, and they're way too broad- they need at least 2 or 3 levels of subcategories to make them halfway usable.

There is no change API wise since the last question.
At best, you could retrieve each package name and scrape the Google Play page. However, this will fail if the app is not present on Google Play.

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 {
private final String TAG = FetchCategoryTask.class.getSimpleName();
private PackageManager pm;
#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

Related

Get all Twitter clients from installed Applications

I'm wondering if it's feasible to list out all Twitter clients that are installed into a phone. At first, I thought this could be done by matching the package name with "Twitter". But most of the Twitter clients on Android don't have 'Twitter' name in their package name.
We can fetch application list with specific permissions but that doesn't going to help me. Fetching applications with certain custom intents probably not going to help as well, and I still have to find a way to get a list of applications that handle a custom Intent.
It doesn't seem feasible but there must be some way that could at least put me close to want I want. Anyone would like to shed some light on it?
I don't know if there is some kind of method to get "twitter client" (how we define Twitter client?).
You can fetch a list of names (the twitter clients you know) on the packages installed on devices.
final List<PackageInfo> apps = context.getPackageManager().getInstalledPackages(0);
final String separator = ";";
final String separatorVersion = "-";
//Log.i("Package list", "num:+"+apps.size());
for (PackageInfo infoApp : apps) {
for (TwitterClient tr : mapTwitterClient.values()) {
if (infoApp.packageName.contains(tr.getPackageName()) ) { //it's a Twitter client this package?
if (!twitterClients.equals("")) {
twittersClients += separator;
}
twitterClients += tr.getCommonName()+separatorVersion+infoApp.versionName;
}
}
}
You need to create the class TwitterClient which just have 2 properties(packageName and commonName) and his getters/setters.
And fill map with all TwitterClient you know (Ex: new TwitterClient("com.twitter.android","Twitter official") );
private static final HashMap<String, TwitterClient> mapTwitterClient
This method it's hard process so use smartly.

Can my app load only the games installed on users device?

I wan that my app should show a list of games installed on user device. Is it possible to that?
One way I think is that I will tell the user to create a folder on desktop suppose named "gamesforXYZapp". Now is it possible that my app will search for this folder and show the games put in that folder in my app?
Is there any other way?
In Android, you cannot set your app as "Game Type" so you cannot filter applications by this category.
I think, a solution to this would be to find all games packages from Google Play and put that list in your app and frequently update it. It needs uninterrupted internet connection so that you could send found apps list to server and server will return back games from that list. So, you need to write server code for that.
If you have a list of 'All Games' on the Platform (like A--C does), you could use the PackageManager to determine which apps are installed on the users device, and then match that list to the 'All Games' list.
This might look something like this:
List<String> allGames = //list of all games on device - not sure where you get this
PackageManager packageManager = getPackageManager();
List<ApplicationInfo> appsList;
appsList = new ArrayList<ApplicationInfo>();
appsList = packageManager.getInstalledApplications(0);
Iterator<ApplicationInfo> it = appsList.iterator();
while (it.hasNext()) {
if (appName != null) {
ApplicationInfo value = (ApplicationInfo) it.next();
if (value != null) {
String appName2 = value.packageName;
if (appName2 != null) {
// Check if this app is in the 'All Games' list
if (allGames.contains(appName2) {
// This is a game
}
}
}
}

How to detect if an android app is a game?

In an app I am developing I need to iterate through the installed apps and detect which ones are games. Is there any way to do this?
I was thinking to a Play Store API that can search for package name and returns its category even if it's only limited to apps on the store. Does something similar exist? Would it be possible?
Is there any alternative way to do it?
This answer is deprecated!
Correct and backwards compatible way to do this is here!
Since Android API version 21, there's finally a way to check if an application is a game.
PackageManager pm = mContext.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(mPackageName,0);
if((ai.flags & ApplicationInfo.FLAG_IS_GAME) == ApplicationInfo.FLAG_IS_GAME)
return true;
return false;
There is no automatical way to detect if an app is a game. You just could compaire the package name of the common part of the package name. My solution was to index the google store pages and hash the package names.
I could optimize my hashes by building common prefixes. I handled the package name as a domain and grep the public suffix. I use the list from http://publicsuffix.org/.
A "public suffix" is one under which Internet users can directly register names. Some examples of public suffixes are .com, .co.uk and pvt.k12.ma.us. The Public Suffix List is a list of all known public suffixes.
The Public Suffix List is an initiative of Mozilla, but is maintained as a community resource. It is available for use in any software, but was originally created to meet the needs of browser manufacturers.
With this list you can detect part of a packagename is a common prefix.
For me the above answer didn't work, the ApplicationInfo.FLAG_IS_GAME is now deprecated, with API 28+ (in my case), you can do something like this:
_pm = _context.PackageManager;
List<string> packageList = new List<string>();
Intent intent = new Intent(Intent.ActionMain);
intent.AddCategory(Intent.CategoryLeanbackLauncher); // or add any category you want
var list = _pm.QueryIntentActivities(intent, PackageInfoFlags.MetaData);
foreach (var app in list)
{
ApplicationInfo ai = _pm.GetApplicationInfo(app.ActivityInfo.PackageName, 0);
var allFlags = ai.Flags;
if (allFlags.HasFlag(ApplicationInfoFlags.IsGame))
{
packageList.Add(app.ActivityInfo.PackageName);
}
}

how do I know where my application comes from?

I need your help. I have two questions !
1) How can I know where an application I download comes from? Google Play or others.
I use something like that to get some informations about installed packages; but I didn't found the way to get where a package come from ! http://myandroidStore.com/myNewGame.apk for exemple.
List<PackageInfo> packages = getActivity() .getPackageManager()
.getInstalledPackages(0);
for (int i=0; i<packages.size(); i++) {
PackageInfo packageInfo = packages.get(i);
AppList tmpList = new AppList();
tmpList.applicationName = packageInfo.applicationInfo.loadLabel(getActivity()
.getPackageManager()).toString();
tmpList.packageName = packageInfo.packageName;
tmpList.versionName = packageInfo.versionName;
tmpList.versionCode = packageInfo.versionCode;
tmpList.provider = packageInfo.providers;
tmpList.firstInstallTime = packageInfo.firstInstallTime;
tmpList.lastUpdateTime = packageInfo.lastUpdateTime;
tmpList.signatures = packageInfo.signatures;
}
2) When "Unknown Sources" isn't selected I can't download application beyond Google Play.
Do you have an idea how Android check this verification?
1) How can I know where an application I download comes from? Google Play or others.
AFAIK the system provides no means for you to get this information. If you are interested in obtaining it you'd have to make seperate apk files with something unique embedded in them, that way you'd know based on that unique string where the apk came from at runtime.
2) When "Unknown Sources" isn't selected I can't download application beyond Google Play. Do you have an idea how Android check this verification?
I assume that the PackageManager is what is making the check for this. Not certain though.

How can I do an Amazon App Store search using an Intent and filter it by developer name?

Is there a way to start an Intent on the Kindle Fire that will cause the AppStore app to open and display all the apps for a certain developer? For instance, on a phone/tablet with the Android Market installed, I can do this:
Intent otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("market://search?q=pub:\"" + developerName + "\""));
activity.startActivity(otherApps);
And show all my apps in the Android Market. Can I do that with the Amazon App Store? If so, how? I've tried that Intent with other seemingly valid names (such as "ZeptoLab") and I don't get any filtering. It just drops me in the full unfiltered App Store. Looking up a specific app with "market://details?id=package.name" does seem to work.
From https://developer.amazon.com/help/faq.html#Marketing:
To point to your app for marketing purposes use the URL http://www.amazon.com/gp/mas/dl/android?p=packagename (where packagename is your app package name).
If you want to link to the list of all your applications on the Amazon Appstore use the URL http://www.amazon.com/gp/mas/dl/android?p=packagename&showAll=1.
e.g. http://www.amazon.com/gp/mas/dl/android?p=com.rovio.angrybirds&showAll=1
All this can be seen here: https://developer.amazon.com/sdk/in-app-purchasing/sample-code/deeplink.html
Update(deep linking):
amzn://apps/android?p=
Best way is to look at their website (or here), which currently states this :
search: amzn://apps/android?s=amazon%20mp3 or http://www.amazon.com/gp/mas/dl/android?s=amazon%20mp3
detail page using package name: amzn://apps/android?p=com.amazon.mp3 or http://www.amazon.com/gp/mas/dl/android?p=com.amazon.mp3
detail page using unique ID ("asin") : amzn://apps/android?asin=B004FRX0MY or http://www.amazon.com/gp/mas/dl/android?asin=B004FRX0MY
show all apps of the developer who made the app: amzn://apps/android?p=com.amazon.mp3&showAll=1 or http://www.amazon.com/gp/mas/dl/android?p=com.amazon.mp3&showAll=1
Amazon supports their own deep links now: https://developer.amazon.com/appsandservices/apis/earn/in-app-purchasing/docs/deeplink
E.g. you can start an intent with uri amzn://apps/android?p=my.package.name.
From - https://developer.amazon.com/help/tuabg.html
For in-app advertising or mobile browser based linking, please:
Use this link structure: http:// www.amazon.com/gp/mas/dl/android?p=com.example.package/ref=mas_pm_app_name
For a link that directs to a list of all of your apps within our U.S. store, please:
Use this link structure: http://www.amazon.com/gp/mas/dl/android?p=com.example.package&showAll=1
Now, you think amazon would have this correct on their own website, but the first part that I put in bold is wrong. This is what it should actually be:
http://www.amazon.com/gp/mas/dl/android?p=com.example.package&ref=mas_pm_app_name
Notice the & instead of the / between the package name and ref. Hopefully this helps some other people since this little detail wasted some of my time...
Here's the solution I came up with using the advice below from chiuki:
I added a boolean to one of my resource files that indicates whether or not the app is published in the Amazon AppStore or Android Market. Yeah, you have to change it whenever you publish your app, but think of it sort of like remembering to set debuggable to "false" when you publish. Put it on a check list. It goes like this:
In resource file:
<bool name="app_is_in_amazon_app_store">true< /bool>
In code:
public class SomeUtil
{
private static Boolean isInAmazonAppStore;
public static boolean isInAmazonAppStore(Activity activity)
{
if (isInAmazonAppStore == null)
{
isInAmazonAppStore = activity.getResources().getBoolean(R.bool.app_is_in_amazon_app_store) ;
}
return isInAmazonAppStore;
}
public static void startOtherMarketAppsActivity(Activity activity)
{
try
{
Intent otherApps = null;
if (isInAmazonAppStore(activity))
{
otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.amazon.com/gp/mas/dl/android?p=" + getPackageNameInAmazonAppStore(activity) + "&showAll=1"));
}
else
{
otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("market://search?q=pub:\"" + getAndroidDeveloperName(activity) + "\""));
}
activity.startActivity(otherApps);
}
catch(Exception ex){ /* error handling */}
}

Categories

Resources