Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android得到已安裝和未安裝apk的信息

android得到已安裝和未安裝apk的信息

編輯:關於Android編程

在獲取apk資源時候最重要的一個類就是PackageManager,我們可以通過這個類得到各種想要的東西,首先是得到已經安裝的apk的基本信息,包括label,和圖標等資源:

 

PackageManager pm = getPackageManager();
List apkInfos = pm.getInstalledPackages(0);
ArrayList infos_name =  new ArrayList() ;//用來存放label
ArrayList infos_icon = newArrayList();//用來存儲apk啟動圖標資源
String name = "";
   Drawable icon;
   PackageInfo apk;
   for (int i = 0; i < apkInfos.size(); )
   {
      apk = apkInfos.get(i);
      i++;
      name = (String) pm.getApplicationLabel(apk.applicationInfo);
      icon = pm.getApplicationIcon(apk.applicationInfo);
      infos_icon.add(icon);
      infos_name.add(name);
   }
接下來我們利用PackageManager獲得已安裝apk中的activity,和service等

 

 

ListpackagesInfo =  pm.getInstalledPackages(0);
for (PackageInfo packageInfo : packagesInfo) {
	Log.d("TAG","packageInfo NAME IS :"+packageInfo.packageName);
}


PackageManager pm = getPackageManager();
try {   
//獲得com.example.pertest包中的activity,service和broadcastreceiver
PackageInfo packageInfo = pm.getPackageInfo("com.example.pertest",
				PackageManager.GET_PERMISSIONS
						| PackageManager.GET_SERVICES
						| PackageManager.GET_RECEIVERS);
	ActivityInfo[] activities = packageInfo.activities;

	if (activities != null) {
		for (ActivityInfo activityInfo : activities) {
			Log.d("TAG", "the activity " + activityInfo.toString()
					+ "==" + packageInfo.versionCode + "==="
					+ packageInfo.versionName);
		}
	} else {
		Log.d("TAG", "the activity is null");
	}
	ServiceInfo[] serviceInfos = packageInfo.services;
	for (ServiceInfo serviceInfo : serviceInfos) {
		Log.d("TAG", "service name is :" + serviceInfo.name);
	}

	activities = packageInfo.receivers;
	for (ActivityInfo activity : activities) {
		Log.d("TAG", "receiver is :" + activity.name);
	}
} catch (NameNotFoundException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

上面就是獲取已經安裝的apk的基本信息,接下來看看如何獲取未安裝的apk文件的基本信息,這對於android動態加載時很有用的,我們來看:

 

得到未安裝apk的圖標:

 

public static Drawable getAppIcon(Context context, String apkFilepath) {
        PackageManager pm = context.getPackageManager();
        PackageInfo pkgInfo = getPackageInfo(context, apkFilepath);
        if (pkgInfo == null) {
            return null;
        }

        ApplicationInfo appInfo = pkgInfo.applicationInfo;
        if (Build.VERSION.SDK_INT >= 8) {
            appInfo.sourceDir = apkFilepath;
            appInfo.publicSourceDir = apkFilepath;
        }
        return pm.getApplicationIcon(appInfo);
    }
得到未安裝apk的名稱:

 

 

public static CharSequence getAppLabel(Context context, String apkFilepath) {
        PackageManager pm = context.getPackageManager();
        PackageInfo pkgInfo = getPackageInfo(context, apkFilepath);
        if (pkgInfo == null) {
            return null;
        }
        ApplicationInfo appInfo = pkgInfo.applicationInfo;
        if (Build.VERSION.SDK_INT >= 8) {
            appInfo.sourceDir = apkFilepath;
            appInfo.publicSourceDir = apkFilepath;
        }

        return pm.getApplicationLabel(appInfo);
 }
如果還覺得不夠的話,我們可以得到:PackageInfo對象,通過該對象,我們就可以獲得該未安裝apk的activity,service,broadcastreceiver等,方法同"獲得已安裝apk中的activity,和service" ,代碼如下:

 

 

//得到PackageInfo對象,其中包含了該apk包含的activity和service
public static PackageInfo getPackageInfo(Context context, String apkFilepath) {
        PackageManager pm = context.getPackageManager();
        PackageInfo pkgInfo = null;
        try {
            pkgInfo = pm.getPackageArchiveInfo(apkFilepath, PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
        } catch (Exception e) {
            // should be something wrong with parse
            e.printStackTrace();
        }
        return pkgInfo;
    }

在android動態加載的時候,是通過DexClassLoader來實現的,通過這種方式來獲取未安裝程序的DexClassLoader對象:

 

 

String mNativeLibDir = mContext.getDir("pluginlib", Context.MODE_PRIVATE).getAbsolutePath();
 private DexClassLoader createDexClassLoader(String dexPath) {
        File dexOutputDir = mContext.getDir("dex", Context.MODE_PRIVATE);
        dexOutputPath = dexOutputDir.getAbsolutePath();
        DexClassLoader loader = new DexClassLoader(dexPath, dexOutputPath, mNativeLibDir, mContext.getClassLoader());
        return loader;
 }
第一個參數dexPath就是我們apk的存放路徑。

 

第二個參數dexOutPath就是該apk文件對應的dex文件的存放路徑,不可以為null。

第三個參數是目標類中使用的C/C++庫的列表,每個目錄用File.pathSeparator間隔開; 可以為 null。

第四個參數是該類裝載器的父裝載器,一般用當前執行類的裝載器。

在獲得了該DexClassLoader對象以後,我們就可以實現動態加載該apk中的方法了,詳細的方法,請看我的另一篇文章:android動態加載

對於加載未安裝的apk中的資源,由於使用的是不同的context,所以,這裡先這樣做:

 

 private AssetManager createAssetManager(String dexPath) {
        try {
            AssetManager assetManager = AssetManager.class.newInstance();
            Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
            addAssetPath.invoke(assetManager, dexPath);
            return assetManager;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


private Resources createResources(AssetManager assetManager) {
        Resources superRes = mContext.getResources();
        Resources resources = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
        return resources;
}
此時的assetManager和resources就可以和平時一樣來用了。

 




 


 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved