`

android 获取应用程序(包)的信息和缓存大小 PackageManager的使用

 
阅读更多
PackageManger 类
说明: 获得已安装的应用程序信息 。可以通过getPackageManager()方法获得。
常用方法:
    public abstract PackageManager  getPackageManager()  
     功能:获得一个PackageManger对象
    public abstrac  tDrawable    getApplicationIcon(StringpackageName)
      参数: packageName 包名
      功能:返回给定包名的图标,否则返回null

    public abstract ApplicationInfo   getApplicationInfo(String packageName, int flags)

      参数:packagename 包名
                           flags 该ApplicationInfo是此flags标记,通常可以直接赋予常数0即可
      功能:返回该ApplicationInfo对象

     public abstract List<ApplicationInfo>  getInstalledApplications(int flags)
      参数:flag为一般为GET_UNINSTALLED_PACKAGES,那么此时会返回所有ApplicationInfo。我们可以对ApplicationInfo的flags过滤,得到我们需要的。
      功能:返回给定条件的所有PackageInfo

     public abstract List<PackageInfo>  getInstalledPackages(int flags)
      参数如上
      功能:返回给定条件的所有PackageInfo

     public abstractResolveInfo  resolveActivity(Intent intent, int flags)
       参数:  intent 查寻条件,Activity所配置的action和category
       flags: MATCH_DEFAULT_ONLY    :Category必须带有CATEGORY_DEFAULT的Activity,才匹配
       GET_INTENT_FILTERS         :匹配Intent条件即可
       GET_RESOLVED_FILTER    :匹配Intent条件即可
       功能 :返回给定条件的ResolveInfo对象(本质上是Activity)

       public abstract  List<ResolveInfo>  queryIntentActivities(Intent intent, int flags)
       参数同上
       功能 :返回给定条件的所有ResolveInfo对象(本质上是Activity),集合对象

       public abstract ResolveInfo  resolveService(Intent intent, int flags)
           参数同上
           功能 :返回给定条件的ResolveInfo对象(本质上是Service)

     public abstract List<ResolveInfo> queryIntentServices(Intent intent, int flags)
          参数同上
          功能 :返回给定条件的所有ResolveInfo对象(本质上是Service),集合对象

案例讲解

通过queryIntentActivities()方法,查询Android系统的所有具备ACTION_MAIN和CATEGORY_LAUNCHER的Intent的应用程序,点击后,能启动该应用,说白了就是做一个类似Home程序的简易Launcher 。



布局文件
<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical" android:layout_width="fill_parent"  
    android:layout_height="fill_parent">>  
    <ListView android:id="@+id/listviewApp" android:layout_width="fill_parent"  
        android:layout_height="fill_parent" ></ListView>  
</LinearLayout>  


<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent" android:layout_height="50dip">  
  
    <ImageView android:id="@+id/imgApp" android:layout_width="wrap_content"  
        android:layout_height="fill_parent" ></ImageView>  
    <RelativeLayout android:layout_width="fill_parent"  android:layout_marginLeft="10dip"  
        android:layout_height="40dip">  
        <TextView android:id="@+id/tvLabel" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:text="AppLable : "></TextView>  
        <TextView android:id="@+id/tvAppLabel" android:layout_width="wrap_content"  
            android:layout_toRightOf="@id/tvLabel" android:layout_height="wrap_content"  
            android:layout_marginLeft="3dip" android:text="Label" android:textColor="#FFD700"></TextView>  
        <TextView android:id="@+id/tvName" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:layout_below="@id/tvLabel"   
            android:text="包名:"></TextView>  
        <TextView android:id="@+id/tvPkgName" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:layout_below="@id/tvAppLabel"  
            android:layout_alignLeft="@id/tvAppLabel" android:textColor="#FFD700"></TextView>  
    </RelativeLayout>  
</LinearLayout> 


自定义适配器类
//自定义适配器类,提供给listView的自定义view
public class BrowseApplicationInfoAdapter extends BaseAdapter {
	
	private List<AppInfo> mlistAppInfo = null;
	
	LayoutInflater infater = null;
    
	public BrowseApplicationInfoAdapter(Context context,  List<AppInfo> apps) {
		infater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mlistAppInfo = apps ;
	}
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		System.out.println("size" + mlistAppInfo.size());
		return mlistAppInfo.size();
	}
	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return mlistAppInfo.get(position);
	}
	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public View getView(int position, View convertview, ViewGroup arg2) {
		System.out.println("getView at " + position);
		View view = null;
		ViewHolder holder = null;
		if (convertview == null || convertview.getTag() == null) {
			view = infater.inflate(R.layout.browse_app_item, null);
			holder = new ViewHolder(view);
			view.setTag(holder);
		} 
		else{
			view = convertview ;
			holder = (ViewHolder) convertview.getTag() ;
		}
		AppInfo appInfo = (AppInfo) getItem(position);
		holder.appIcon.setImageDrawable(appInfo.getAppIcon());
		holder.tvAppLabel.setText(appInfo.getAppLabel());
		holder.tvPkgName.setText(appInfo.getPkgName());
		return view;
	}

	class ViewHolder {
		ImageView appIcon;
		TextView tvAppLabel;
		TextView tvPkgName;

		public ViewHolder(View view) {
			this.appIcon = (ImageView) view.findViewById(R.id.imgApp);
			this.tvAppLabel = (TextView) view.findViewById(R.id.tvAppLabel);
			this.tvPkgName = (TextView) view.findViewById(R.id.tvPkgName);
		}
	}
}


MainActivity.java 主工程逻辑
请仔细体会queryIntentActivities()方法,并且注意到排序,它很重要。
public class MainActivity extends Activity implements OnItemClickListener {  
  
    private ListView listview = null;  
  
    private List<AppInfo> mlistAppInfo = null;  
  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.browse_app_list);  
  
        listview = (ListView) findViewById(R.id.listviewApp);  
        mlistAppInfo = new ArrayList<AppInfo>();  
        queryAppInfo(); // 查询所有应用程序信息  
        BrowseApplicationInfoAdapter browseAppAdapter = new BrowseApplicationInfoAdapter(  
                this, mlistAppInfo);  
        listview.setAdapter(browseAppAdapter);  
        listview.setOnItemClickListener(this);  
    }  
    // 点击跳转至该应用程序  
    public void onItemClick(AdapterView<?> arg0, View view, int position,  
            long arg3) {  
        // TODO Auto-generated method stub  
        Intent intent = mlistAppInfo.get(position).getIntent();  
        startActivity(intent);  
    }  
    // 获得所有启动Activity的信息,类似于Launch界面  
    public void queryAppInfo() {  
        PackageManager pm = this.getPackageManager(); // 获得PackageManager对象  
        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);  
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
        // 通过查询,获得所有ResolveInfo对象.  
        List<ResolveInfo> resolveInfos = pm  
                .queryIntentActivities(mainIntent, PackageManager.MATCH_DEFAULT_ONLY);  
        // 调用系统排序 , 根据name排序  
        // 该排序很重要,否则只能显示系统应用,而不能列出第三方应用程序  
        Collections.sort(resolveInfos,new ResolveInfo.DisplayNameComparator(pm));  
        if (mlistAppInfo != null) {  
            mlistAppInfo.clear();  
            for (ResolveInfo reInfo : resolveInfos) {  
                String activityName = reInfo.activityInfo.name; // 获得该应用程序的启动Activity的name  
                String pkgName = reInfo.activityInfo.packageName; // 获得应用程序的包名  
                String appLabel = (String) reInfo.loadLabel(pm); // 获得应用程序的Label  
                Drawable icon = reInfo.loadIcon(pm); // 获得应用程序图标  
                // 为应用程序的启动Activity 准备Intent  
                Intent launchIntent = new Intent();  
                launchIntent.setComponent(new ComponentName(pkgName,  
                        activityName));  
                // 创建一个AppInfo对象,并赋值  
                AppInfo appInfo = new AppInfo();  
                appInfo.setAppLabel(appLabel);  
                appInfo.setPkgName(pkgName);  
                appInfo.setAppIcon(icon);  
                appInfo.setIntent(launchIntent);  
                mlistAppInfo.add(appInfo); // 添加至列表中  
                System.out.println(appLabel + " activityName---" + activityName  
                        + " pkgName---" + pkgName);  
            }  
        }  
    }  
}


转自:http://blog.csdn.net/qinjuning/article/details/6867806


下面部分的内容是如何获取安装包得大小,包括缓存大小(cachesize)、数据大小(datasize)、应用程序大小(codesize)。
本部分的知识点涉及到AIDL、Java反射机制。理解起来也不是很难。
  
      关于安装包得大小信息封装在PackageStats类中,该类很简单,只有几个字段:
      PackageStats类:
          常用字段:
               public long cachesize      缓存大小
               public long codesize       应用程序大小
               public long datasize       数据大小
               public String packageName  包名

        PS:应用程序的总大小 = cachesize  + codesize  + datasize
        也就是说只要获得了安装包所对应的PackageStats对象,就可以获得信息了。但是在AndroidSDK中并没有显示提供方法来
获得该对象,是不是很苦恼呢?但是,我们可以通过放射机制来调用系统中隐藏的函数(@hide)来获得每个安装包得信息。

package com.qin.appsize;


import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.qin.appsize.AppInfo;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.format.Formatter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class MainActivity extends Activity implements OnItemClickListener{
    private static String TAG = "APP_SIZE";

	private ListView listview = null;
	private List<AppInfo> mlistAppInfo = null;
	LayoutInflater infater = null ; 
	//全局变量,保存当前查询包得信息
	private long cachesize ; //缓存大小
	private long datasize  ;  //数据大小 
	private long codesize  ;  //应用程序大小
	private long totalsize ; //总大小
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.browse_app_list);
        listview = (ListView) findViewById(R.id.listviewApp);
		mlistAppInfo = new ArrayList<AppInfo>();
		queryAppInfo(); // 查询所有应用程序信息
		BrowseApplicationInfoAdapter browseAppAdapter = new BrowseApplicationInfoAdapter(
				this, mlistAppInfo);
		listview.setAdapter(browseAppAdapter);
		listview.setOnItemClickListener(this);
    }
     // 点击弹出对话框,显示该包得大小
	public void onItemClick(AdapterView<?> arg0, View view, int position,long arg3) {
        //更新显示当前包得大小信息
		queryPacakgeSize(mlistAppInfo.get(position).getPkgName()); 
        
		infater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View dialog = infater.inflate(R.layout.dialog_app_size, null) ;
		TextView tvcachesize =(TextView) dialog.findViewById(R.id.tvcachesize) ; //缓存大小
		TextView tvdatasize = (TextView) dialog.findViewById(R.id.tvdatasize)  ; //数据大小
		TextView tvcodesize = (TextView) dialog.findViewById(R.id.tvcodesize) ; // 应用程序大小
		TextView tvtotalsize = (TextView) dialog.findViewById(R.id.tvtotalsize) ; //总大小
		//类型转换并赋值
		tvcachesize.setText(formateFileSize(cachesize));
		tvdatasize.setText(formateFileSize(datasize)) ;
		tvcodesize.setText(formateFileSize(codesize)) ;
		tvtotalsize.setText(formateFileSize(totalsize)) ;
		//显示自定义对话框
		AlertDialog.Builder builder =new AlertDialog.Builder(MainActivity.this) ;
		builder.setView(dialog) ;
		builder.setTitle(mlistAppInfo.get(position).getAppLabel()+"的大小信息为:") ;
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.cancel() ;  // 取消显示对话框
			}
			
		});
		builder.create().show() ;
	}
    public void  queryPacakgeSize(String pkgName) throws Exception{
    	if ( pkgName != null){
    		//使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfo
    		PackageManager pm = getPackageManager();  //得到pm对象
    		try {
    			//通过反射机制获得该隐藏函数
				Method getPackageSizeInfo = pm.getClass().getDeclaredMethod("getPackageSizeInfo", String.class,IPackageStatsObserver.class);
			    //调用该函数,并且给其分配参数 ,待调用流程完成后会回调PkgSizeObserver类的函数
			    getPackageSizeInfo.invoke(pm, pkgName,new PkgSizeObserver());
			} 
        	catch(Exception ex){
        		Log.e(TAG, "NoSuchMethodException") ;
        		ex.printStackTrace() ;
        		throw ex ;  // 抛出异常
        	} 
    	}
    }
   
    //aidl文件形成的Bindler机制服务类
    public class PkgSizeObserver extends IPackageStatsObserver.Stub{
        /*** 回调函数,
         * @param pStatus ,返回数据封装在PackageStats对象中
         * @param succeeded  代表回调成功
         */ 
		@Override
		public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
				throws RemoteException {
			// TODO Auto-generated method stub
		   cachesize = pStats.cacheSize  ; //缓存大小
		    datasize = pStats.dataSize  ;  //数据大小 
		    codesize = pStats.codeSize  ;  //应用程序大小
		    totalsize = cachesize + datasize + codesize ;
			Log.i(TAG, "cachesize--->"+cachesize+" datasize---->"+datasize+ " codeSize---->"+codesize)  ;
		}
    }
    //系统函数,字符串转换 long -String (kb)
    private String formateFileSize(long size){
    	return Formatter.formatFileSize(MainActivity.this, size); 
    }
   // 获得所有启动Activity的信息,类似于Launch界面
	public void queryAppInfo() {
		PackageManager pm = this.getPackageManager(); // 获得PackageManager对象
		Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
		mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
		// 通过查询,获得所有ResolveInfo对象.
		List<ResolveInfo> resolveInfos = pm.queryIntentActivities(mainIntent, 0);
		// 调用系统排序 , 根据name排序
		// 该排序很重要,否则只能显示系统应用,而不能列出第三方应用程序
		Collections.sort(resolveInfos,new ResolveInfo.DisplayNameComparator(pm));
		if (mlistAppInfo != null) {
			mlistAppInfo.clear();
			for (ResolveInfo reInfo : resolveInfos) {
				String activityName = reInfo.activityInfo.name; // 获得该应用程序的启动Activity的name
				String pkgName = reInfo.activityInfo.packageName; // 获得应用程序的包名
				String appLabel = (String) reInfo.loadLabel(pm); // 获得应用程序的Label
				Drawable icon = reInfo.loadIcon(pm); // 获得应用程序图标
				// 为应用程序的启动Activity 准备Intent
				Intent launchIntent = new Intent();
				launchIntent.setComponent(new ComponentName(pkgName,activityName));
				// 创建一个AppInfo对象,并赋值
				AppInfo appInfo = new AppInfo();
				appInfo.setAppLabel(appLabel);
				appInfo.setPkgName(pkgName);
				appInfo.setAppIcon(icon);
				appInfo.setIntent(launchIntent);
				mlistAppInfo.add(appInfo); // 添加至列表中
			}
		}
	}
}


转自:http://blog.csdn.net/qinjuning/article/details/6892054














  • 大小: 36.6 KB
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Android中获取应用程序(包)的信息 PackageManager的使用

    本文将详细讲解如何利用`PackageManager`来获取Android应用程序(包)的相关信息。 首先,让我们理解`PackageManager`的基本概念。它是Android系统服务的一部分,允许应用程序访问和操作其他已安装的应用程序的元...

    android获取应用程序大小,缓存数据信息

    在Android系统中,获取应用程序的大小、数据大小以及缓存数据是开发者或用户进行性能优化、存储管理的重要操作。下面将详细介绍如何实现这些功能,并解释相关知识点。 首先,我们需要了解Android应用的存储结构。每...

    Android中获取应用程序(包)的大小-----PackageManager的使用(二)

    本文将详细讲解如何通过Android的`PackageManager`服务来获取应用程序的大小,以及背后的实现原理。 首先,我们需要理解`PackageManager`在Android中的角色。`PackageManager`是Android系统的一个核心组件,它负责...

    Android中获取应用程序(包)的信息-PackageManager的使用方法

    ### Android中获取应用程序(包)的信息—PackageManager的使用方法 #### 概述 在Android开发过程中,有时我们需要获取系统中应用程序的信息,例如包名(`packagename`)、标签(`label`)、图标(`icon`)以及占用...

    android获取应用程序信息小Demo

    在Android开发中,获取应用程序的信息是一项常见的任务,这有助于开发者监控应用的状态,或者为用户提供关于应用的详细信息。本教程将通过一个小型的Demo来演示如何获取应用的名称、版本、缓存大小以及应用程序的...

    Android获取应用程序大小和缓存的实例代码

    以上就是Android获取应用程序大小和缓存的实例代码的核心部分。通过这样的实现,开发者可以轻松地列出设备上所有应用的大小和缓存信息,从而帮助用户管理和清理存储空间。这个功能在系统优化工具或者第三方应用管理...

    获取应用程序大小

    在Android开发中,获取应用程序的大小是一个常见的需求,这有助于我们了解应用的资源占用情况,优化性能,或者在用户界面中提供相关信息。本项目提供的源码将帮助开发者实现这一功能。下面,我们将深入探讨如何在...

    获取安装后的app所占空间大小

    3. **缓存大小**:应用程序在运行过程中可能会生成缓存文件,以提高数据加载速度。这些文件存储在特定的缓存目录下,如`Android/data/&lt;package_name&gt;/cache`。 4. **数据大小**:这包括应用在内部存储或外部存储...

    利用aidl和反射获取应用的缓存,应用大小等数据

    在Android系统中,开发者可以利用Android Interface Definition Language (AIDL) 和反射机制来获取应用程序的缓存信息以及应用的整体大小。下面将详细讲解这两个技术及其在获取这些数据时的应用。 **一、Android ...

    Android获取应用程序大小的方法

    今天碰到个问题,想获取某个已安装的包的大小... 再后来,我想起系统的设置里面有一个应用程序管理,它里面列出了所有程序的占用空间大小、数据大小和缓存大小。恩,这个就是突破口。以前写过一篇获取其他包的Context

    Android 8.0的缓存大小和缓存清理接口方法

    Android 8.0 的缓存大小和缓存清理接口方法的实现有所不同,需要使用 `StorageStatsManager` 和 `StorageStats` 类来获取缓存大小,并使用 `PackageManager` 类的 `deleteApplicationCacheFiles` 方法来清理缓存。...

    Android获取app应用程序大小的方法

    在Android平台上,获取应用程序的大小通常涉及到访问系统级的API,因为这些信息是私有的,普通应用无法直接访问。为了实现这一目标,我们需要利用AIDL(Android Interface Definition Language)和Java的反射机制。...

    Android应用管理器

    在Android操作系统中,应用管理器(App Manager)是一款至关重要的工具,它允许用户对设备上的应用程序进行有效的管理和控制。这款应用管理器具有多种实用功能,包括卸载应用、启动应用、查看应用信息以及对应用进行...

    通过反射和aidl获取应用大小

    在Android开发中,有时我们需要获取应用的大小信息,这包括安装包的大小以及在设备上占用的存储空间。本文将详细介绍如何通过反射和AIDL(Android Interface Definition Language)这两种技术来实现这一目标。 首先...

    获取应用大小需要的aidl文件

    总结,通过AIDL,我们可以构建一个跨进程的服务,来获取应用程序的大小信息。这需要对Android的IPC机制、服务、权限管理以及文件系统有一定的了解。虽然通常情况下,我们可以通过Android的`PackageManager`来获取...

    Android高级应用源码-软件管理器.zip

    软件管理器作为一个常见的系统工具,它能够帮助用户安装、卸载、管理和优化手机上的应用程序,是Android系统中不可或缺的一部分。 首先,我们来看“软件管理器”的核心功能。在Android中,管理应用程序通常涉及到...

    解析Android 如何获得已安装应用大小

    在`onGetStatsCompleted()`回调方法中,你可以获取到`PackageStats`对象,其中包含了`codeSize`(应用程序大小)、`dataSize`(数据大小)和`cacheSize`(缓存大小)。 在实际应用中,由于`getPackageSizeInfo()`是...

    IPackageStatsObserver.aidl和PackageStats.aidl

    使用这两个AIDL文件,开发者可以编写程序来获取应用的缓存大小。这在清理缓存、优化存储空间或者监控应用性能时非常有用。通常步骤如下: - 创建一个实现了`IPackageStatsObserver`的类,并重写`...

Global site tag (gtag.js) - Google Analytics