8

我有两个或多个具有我指定类别的应用程序,例如

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

我可以通过以下方式获得所有具有此类别的软件包:

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

现在我想跟踪我的类别应用程序安装并从应用程序中删除,所以我制作了一个广播接收器,它将为我提供已安装或已删除应用程序的包名称,但是我如何使用包名称来控制应用程序的类别以确定这是否是不是我的应用程序。我可以为指定的类别应用程序制作广播接收器吗?如果不是,我如何从包名中获取类别。

4

3 回答 3

0

感谢 Rishabh Jain 的好答案,我对代码进行了一些小调整以便于使用

在 build.gradle 应用级别文件中:

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

在清单中添加互联网权限

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

在活动/片段/对话框或任何地方:

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();
于 2022-01-04T12:38:06.277 回答
0

我也面临同样的问题。上述查询的解决方案如下所述。

首先,下载Jsoup库或下载jar文件。

或者

将此添加到您的 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());
        }
    }

}

作为回报,您将获得应用程序公司名称和应用程序类别

于 2018-12-16T13:20:15.623 回答
-1

您可以使用另一种方法。在您的应用程序清单中设置元信息,而不是为您的活动设置类别。请注意,无法再检索已删除的包信息(如果尚未使用标志 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>

添加广播接收器以跟踪软件包安装。检查包的元信息以查看您的值已经存在。

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        
}
}

如您所见,任何其他应用程序都可以在其清单中设置您的元数据,因此这不是识别您自己的应用程序的安全方法。最好的方法是检查 apk 签名是否都使用相同的证书签名。

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
    }
}
于 2014-08-07T12:12:11.070 回答