Android 下得到 未安装APK包含信息 等

很多情况下,我们需要通过APK文件来得到它的一些信息。 (此时此APK不一定被安装了)

0. 基础知识:
可以通过android.content.Context的方法 getPackageManager()得到一个PackageManager实例。
PackageManager有一个方法:
PackageInfo getPackageArchiveInfo (String archiveFilePath, int flags);
其中参数一:archiveFilePath。就是指一个APK文件绝对路径。

请注意它的返回值。是个PackageInfo。它包含Pakcage所有信息,可以认为,这些信息都是从AndroidManifest.xml中收集而来。



1. 得到APK中Activity信息:
PackageInfo中包含:public ActivityInfo[] activities
它会得到AndroidManifest.xml中<application>中所有<Activity> tag.

例如:

<application android:label="@string/app_name"
                 android:debuggable="true">
        <activity android:name=".HelloJni"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

ActivityInfo:从 AndroidManifest.xml's <activity> and <receiver> tags得到的信息。


可以从这一项中得到和Activity有关的所有信息。这些内容都是从<activity>或<receiver>中得到。

例1:得到Activity各信息:
想要得到Activity信息,需要参数2设置为: PackageManager.GET_ACTIVITIES 
PackageInfo PI = PM.getPackageArchiveInfo("/data/hellojni.apk",PackageManager.GET_ACTIVITIES);

 //PackageInfo中得到的PackageName
Log.w("3DiJoy", "PackageInfo . PackageName:" + PI.packageName); Log.w("3DiJoy", String.format("There are [%d] Activity", PI.activities.length));
Log.w("3DiJoy", String.format("Activity in Porcess Name: [%s]", PI.activities[0].processName));

//注意:此处第一次看到ProcessName:
//The name of the process this component should run in. From the "android:process" attribute or, //if not set, the same as applicationInfo.processName
//即此项从main.xml中得到,为android:process项目内容。如果没有设置,则与applicationInfo.processName相同。(注1)

//Activity 所在的PackageName。应该与上面PockageInfo中得到的PackageName相同。

Log.w("3DiJoy", "Activity in Package PackageName:" + PI.activities[0].packageName);

//Activity Name:<activity android:name=".HelloJni"。中读取到的
Log.w("3DiJoy", "Activity Name:" + PI.activities[0].name);



2. 得到APK中Application信息:
Information collected from the <application> tag, or null if there was none。
呵呵,如之前所述,其实PackageInfo中所有项目都是从Main.xml中取到的,之前的Activity如此,现在的Application也是如此。

PackageInfo中有一项:
public ApplicationInfo applicationInfo

Log.w("3DiJoy", "Appliction DataDir:" + PI.applicationInfo.dataDir);
Log.w("3DiJoy", "Application SourceDir:" + PI.applicationInfo.sourceDir);
//Log.w("3DiJoy", "Application JNI LIbdir:" + PI.applicationInfo.nativeLibraryDir);
Log.w("3DiJoy", "Application permission:" + PI.applicationInfo.permission);
Log.w("3DiJoy", "Application in porcessName is :" + PI.applicationInfo.processName);//(注2)
Log.w("3DiJoy", String.format("minSDK Version: [%d]", PI.applicationInfo.targetSdkVersion));
Log.w("3DiJoy", "Application Name:" + PI.applicationInfo.name);
Log.w("3DiJoy", "Application in Package " + PI.applicationInfo.packageName);





3.得到APK中版本信息:

//<manifest> tag's "name" attribute.
Log.w("3DiJoy", "PackageInfo . PackageName:" + PI.packageName);

Log.w("3DiJoy", "PackageInfo . Version String:" + PI.versionName);
Log.w("3DiJoy", String.format("Version code:[%d]", PI.versionCode));
分别从: <manifest> tag's versionCode attribute和 <manifest> tag's versionName attribute.中得到信息。











注1: 
ProcessName相关内容:
PI.activities[0].processName .它其实是activityInfo的父类: android.content.pm.ComponentInfo

的成员变量。是指此activity所运行的Process的名字。
此信息从main.xml的 "android:process" attribute中得到。如果没有设置,则与applicationInfo.processName相同。


注2:
PI.applicationInfo.processName 
此Application将要运行的ProcessName.从Main.xml的"process" attribute得到。如果没有设置,则应该与PackageName相同。


注3:
PI.applicationInfo.packageName 
Application所在的PackageName。 


但Sam发现:
在Android2.2下。
从Activity中取得ProcessName,为null.(
PI.activities[0].processName)
从Application中取得ProcessName也为空。(PI.applicationInfo.processName)
但从Application中取得packageName却是正确的(PI.applicationInfo.packageName, 与PI.packageName相同)



注4:
getPackageArchiveInfo () 的参数1, archive 指的就是APK文件。
 
 

1)获取apk文件的图标

  1. public static Drawable getApkFileIcon(String apkPath, Context context) {  
  2.     PackageManager pm = context.getPackageManager();  
  3.     PackageInfo info = pm.getPackageArchiveInfo(apkPath,  
  4.             PackageManager.GET_ACTIVITIES);  
  5.     if (info != null) {  
  6.         ApplicationInfo appInfo = info.applicationInfo;  
  7.         if (appInfo != null) {  
  8.             try {  
  9.                 appInfo.publicSourceDir = apkPath;  
  10.                 return pm.getApplicationIcon(appInfo);  
  11.             } catch (OutOfMemoryError e) {  
  12.             }  
  13.         }  
  14.     }  
  15.     return null;  
  16.   
  17. }  


 

2)获取AndroidManifest.xml中<meta-data>标签中定义的值

  1. PackageManager manager = this.getPackageManager();  
  2.   
  3. try {  
  4.     // 设置PackageManager.GET_META_DATA标识位是必须的  
  5.     PackageInfo info = manager.getPackageInfo(this.getPackageName(),  
  6.             PackageManager.GET_CONFIGURATIONS | PackageManager.GET_META_DATA);  
  7.     Object myChannel = info.applicationInfo.metaData.get("meta-data-key");  
  8.   
  9.     if ((myChannel != null) && (myChannel instanceof Integer)) {  
  10.         // do something  
  11.     }  
  12.   
  13. catch (NameNotFoundException e) {  
  14.     e.printStackTrace();  
  15. }  
 
 
public class test4 extends Activity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);       
        setContentView(R.layout.main);    
        String archiveFilePath="sdcard/download/Law.apk";//安装包路径
        PackageManager pm = getPackageManager();  
        PackageInfo info = pm.getPackageArchiveInfo(archiveFilePath,PackageManager.GET_ACTIVITIES);  
        if(info != null){  
            ApplicationInfo appInfo = info.applicationInfo;  
            String appName = pm.getApplicationLabel(appInfo).toString();  
            String packageName = appInfo.packageName;  //得到安装包名称
            String version=info.versionName;       //得到版本信息     
            Toast.makeText(test4.this, "packageName:"+packageName+";version:"+version, Toast.LENGTH_LONG).show();
            Drawable icon = pm.getApplicationIcon(appInfo);//得到图标信息
            TextView tv = (TextView)findViewById(R.id.tv); //显示图标
            tv.setBackgroundDrawable(icon);
        }  
    }
    
}
 
 
posted @ 2015-03-04 13:50  wikiki  阅读(1003)  评论(0编辑  收藏  举报