如何使用包名获取应用程序的类别

时间:2013-01-09 09:15:29

标签: android android-intent android-install-apk android-broadcast

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

 <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);

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

2 个答案:

答案 0 :(得分:0)

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

首先,下载Jsoup库或download the jar file.

将此添加到您的build.gradle(模块:应用) 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());
        }
    }

}

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

答案 1 :(得分:-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
    }
}