8

I am having two or more application having my specified category like

 <category android:name="com.myapp.MY_CATEGORY"/>

and I am able to get all packages having this category by :

 final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
 mainIntent.addCategory("com.myapp.MY_CATEGORY");
 final List<ResolveInfo> pkgAppsList =getPackageManager().queryIntentActivities( mainIntent, 0);

Now i want to track my category application installation and delete from an app so i have made a broadcast receiver which will give me the package name of installed or deleted application but how can i gate the category of application using the package name to identify whether this is my app or not. can I make the broadcast receiver for specified category applications or if not how can i get the category from packagename.

Piyush Agarwal
  • 25,608
  • 8
  • 98
  • 111
  • did you got the solution for this ? – Sam-In-TechValens May 24 '13 at 13:16
  • How can We programitically get the Category of any app ? – Sam-In-TechValens May 24 '13 at 13:28
  • @Sam-In-TechValens you cannot get the category using package name only thing you can do is extract package name using category. So what i done in broadcast i took the package installed and also took all the packages using the defined category in arraylist and matches with the latest package installed if it matches means the application installed now is my own application. – Piyush Agarwal May 24 '13 at 14:14

3 Answers3

0

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

0

Thanks Rishabh Jain for the good answer, I had a small adjust of code for easy use

In build.gradle app level file:

 // jsoup
 implementation 'org.jsoup:jsoup:1.14.3'

Add internet permission in manifest

<uses-permission android:name="android.permission.INTERNET"/>

In the activity/fragment/dialog or anywhere:

txtCate = findViewById...
txtPublisher = findViewById...

// just in case you don't have applicationInfo yet:
List<ApplicationInfo> lists = context.getPackageManager()
    .getInstalledApplications(PackageManager.GET_META_DATA);
...

String packageName = applicationInfo.packageName;

new Thread(new Runnable() {
        @Override
        public void run() {
            try{
                String query_url = "https://play.google.com/store/apps/details?id="
                + packageName;  

                Document doc = Jsoup.connect(query_url).get();
                Elements link1 = doc.select("a[class=\"hrTbp R8zArc\"]");
               
               
                String s1 = link1.get(0).text();  // the publisher name
                String s2 = link1.get(1).text();  // the category


                // requireActivity().runOnUiThread... if using fragment
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        txtCate.setText(s1);
                        txtPublisher.setText(s2);
                    }
                });
            } catch (Exception ignore){
                txtCate.setText("error");
                txtPublisher.setText("error");
            }
        }
}).start();
Alias
  • 39
  • 1
  • 4
-1

You may use another approach. Set a meta info in your applications manifest rather than setting category to your activities. Note that deleted package info can not be retrieved anymore (if applications haven't been deleted with flag DONT_DELETE_DATA)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.package.name"
    android:versionCode="1"
    android:versionName="1" >

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <meta-data
            android:name="meta-name"
            android:value="meta-value" />
    </application>
</manifest>

Add a broadcast receiver to track package installations. Check meta info of package to see your values are already there.

private BroadcastReceiver packageListener = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {

        Log.i(intent.getAction(), intent.getData().getEncodedSchemeSpecificPart());

        //Currently being installed or deleted package 
        String packageName = intent.getData().getEncodedSchemeSpecificPart();

        Object value = null;            
        try {
            ApplicationInfo appInfo = getPackageManager().getApplicationInfo(packageName,PackageManager.GET_META_DATA);

            //Get meta value if exits
            value = appInfo.metaData.get("meta-name");
        } catch (NameNotFoundException e) {
            Log.e(TAG, "exception occured", e);             
        }
        //check meta info if it is yours        
}
}

As you see that any other applications can set your meta data in their manifest so it is not a secure way to recognize your own apps. Best way is to check apk signatures if all are signed with the same certificate.

private BroadcastReceiver packageListener = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {

        Log.i(intent.getAction(), intent.getData().getEncodedSchemeSpecificPart());

        String packageName = intent.getData().getEncodedSchemeSpecificPart();

        Signature[] signatures = null;
        try {
            PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName,PackageManager.GET_SIGNATURES);

            signatures = packageInfo.signatures;

        } catch (NameNotFoundException e) {
            Log.e(TAG, "exception occured", e);
        }

        //check installed package signature if it matches
    }
}
Fatih S.
  • 341
  • 2
  • 8