androidは他のアプリの情報を取得します。


http://blog.csdn.net/hellolinshoujie/article/details/7325861
前提条件は、システムコンパイルで生成されたクラス.jarファイルが必要です。
 
 **  * Utility method ト get default icon for a. given package  * @パラム archiveFilePath the absolute パス 保存先 the package  * @return the Drawable object 保存先 the package  */    
 
public Drawable getIconFromPackage(String archiveFilePath) {         
 PackageParser packageParser = new PackageParser(archiveFilePath);         
 File sourceFile = new File(archiveFilePath);          
DisplayMetrics metrics = new DisplayMetrics();          
metrics.setToDefaults();          
PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);         
 if (pkg == null)           
return mContext.getResources().getDrawable(R.drawable.android);                  
ApplicationInfo info = pkg.applicationInfo;                    
Resources pRes = mContext.getResources();          
AssetManager assmgr = new AssetManager();          
assmgr.addAssetPath(archiveFilePath);          
Resources res = new Resources(assmgr, pRes.getDisplayMetrics(),               
pRes.getConfiguration());                    
// read the deafult icon of the package         
if (info.icon != 0){              
Drawable icon = res.getDrawable(info.icon);              
return icon;         
 } else {           
return mContext.getResources().getDrawable(R.drawable.android);          
}     
 }  
 
 
一つのアプリで他のアプリリソースを読み取ります。前提条件は二つのアプリが同じプロセスです。
メインプログラムと要
読み込んだアプリのAndroid Manifest.xmlに配置されています。
たとえば:  android:sharedUserId=「comp.android.main.chajian」/メインアプリのパッケージ名
)
 
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.main.chajian"
    android:versionCode="1"
    android:versionName="1.0"
    android:sharedUserId="com.android.main.chajian"
    >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".MainchajianActivity"
            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>

</manifest>
 

package com.android.main.chajian;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainchajianActivity extends Activity {
    /** Called when the activity is first created. */
 private TextView mTextView;
 private Context mSecondContext;
 private void init(){
  mTextView=(TextView)findViewById(R.id.tv);
  try {
   mSecondContext=this.createPackageContext("com.android.second.chajian",Context.CONTEXT_IGNORE_SECURITY);
  } catch (NameNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  mTextView.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    Drawable draw=mSecondContext.getResources().getDrawable(R.drawable.unknown_source);
    mTextView.setBackgroundDrawable(draw);
   }
  });
  
  
 }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        init();
    }
}
サブアプリ==================================================================================== 
 
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.second.chajian"
    android:versionCode="1"
    android:versionName="1.0"
   android:sharedUserId="com.android.main.chajian"
    >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".MainSecondChajianActivity"
            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>

</manifest>
2です。サブアプリの設定ファイル android:sharedUserId=「comp.android.main.chajian」/メインアプリのパッケージ名
 
3です。 comp.android.main.chajianはメインアプリとサブアプリで定義されています。しかもパスは同じです。
 
package com.android.second.chajian;

import android.app.Activity;
import android.os.Bundle;

public class MainSecondChajianActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
 
============================================================================================================================== 
/** *       apk   * *
 @param ctx *
 @param apkPath *
 @return
*/
public static AppInfoData getApkFileInfo(Context ctx, String apkPath) {
System.out.println(apkPath); File apkFile = new File(apkPath);
if (!apkFile.exists() || !apkPath.toLowerCase().endsWith(".apk"))
 { System.out.println("       "); return null; }
AppInfoData appInfoData;
String PATH_PackageParser = "android.content.pm.PackageParser";
String PATH_AssetManager = "android.content.res.AssetManager";
try { //    pkgParserCls      ,    Class<?> pkgParserCls = Class.forName(PATH_PackageParser);
Class<?>[] typeArgs = {String.class}; Constructor<?> pkgParserCt = pkgParserCls.getConstructor(typeArgs);
Object[] valueArgs = {apkPath};
Object pkgParser = pkgParserCt.newInstance(valueArgs); // pkgParserCls   parsePackage  
 DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();//         ,       
 typeArgs = new Class<?>[]{File.class,String.class, DisplayMetrics.class,int.class};
Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod( "parsePackage", typeArgs);
 valueArgs=new Object[]{new File(apkPath),apkPath,metrics,0}; //  pkgParser_parsePackageMtd     
 Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs); //          "applicationInfo"     
if (pkgParserPkg==null) { return null; }
 Field appInfoFld = pkgParserPkg.getClass().getDeclaredField( "applicationInfo"); //   "pkgParserPkg"    "appInfoFld"  
 if (appInfoFld.get(pkgParserPkg)==null) {
return null; }
ApplicationInfo info = (ApplicationInfo) appInfoFld .get(pkgParserPkg); //    assetMagCls      ,  
Class<?> assetMagCls = Class.forName(PATH_AssetManager);
Object assetMag = assetMagCls.newInstance(); // assetMagCls   addAssetPath   typeArgs = new Class[1];
 typeArgs[0] = String.class;
Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod( "addAssetPath", typeArgs);
valueArgs = new Object[1]; valueArgs[0] = apkPath; //  assetMag_addAssetPathMtd  
 assetMag_addAssetPathMtd.invoke(assetMag, valueArgs); //  Resources      ,   
Resources res = ctx.getResources();
typeArgs = new Class[3];
typeArgs[0] = assetMag.getClass();
typeArgs[1] = res.getDisplayMetrics().getClass(); typeArgs[2] = res.getConfiguration().getClass();
Constructor<Resources> resCt = Resources.class .getConstructor(typeArgs); valueArgs = new Object[3];
valueArgs[0] = assetMag;
valueArgs[1] = res.getDisplayMetrics();
valueArgs[2] = res.getConfiguration();
res = (Resources) resCt.newInstance(valueArgs); //  apk     
appInfoData = new AppInfoData(); if (info!=null) {
if (info.icon != 0) {/
/     ,       
Drawable icon = res.getDrawable(info.icon);//   
appInfoData.setAppicon(icon); }
if (info.labelRes != 0) {
String neme = (String) res.getText(info.labelRes);//   
appInfoData.setAppname(neme);
}else {
String apkName=apkFile.getName();
appInfoData.setAppname(apkName.substring(0,apkName.lastIndexOf("."))); }
String pkgName = info.packageName;//   
appInfoData.setApppackage(pkgName
); }else {
return null; } PackageManager pm = ctx.getPackageManager();
PackageInfo packageInfo = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
 if (packageInfo != null) {
appInfoData.setAppversion(packageInfo.versionName);//   
appInfoData.setAppversionCode(packageInfo.versionCode+"");//    }
return appInfoData; }
catch (Exception e)
{ e.printStackTrace();
}
return null; }
 
方法の1:最も直接的なのはappkのパッケージ名とスタートクラス名を知っていて、直接起動します。
    Intent mIntent = new Intent( );   
    ComponentName comp = new ComponentName("  ", "  ");       
    mIntent.setComponent(comp);   
    mIntent.setAction("android.intent.action.VIEW");   
      
    startActivity(mIntent);  

方法2:パッケージ名だけを知っていれば、この場合も通常起動でき、通常はpublicabstract Intent getLaunchIntentForPackage(String package Name)を呼び出します。
プログラムの入り口に戻るIntentとは、JavaプログラムのMain方法のことです。直接startActivity(戻るintent)でいいです。
Intent mIntent= getPackage Manager()getLaunchIntentForPackage(package Name);
if(mIntent!=null)startActivity(mIntent)
方法の3:どのようにしてappkだけを提供して、どのようにスタートしますか?この場合、通常はsdkソースコードでコンパイルするしかないです。
Android.com.pm.Package Paserは、通常導入される。
コードを参照:
    /*   
     
     * Utility method to get application information for a given packageURI 
     
     */  
      
    public   ApplicationInfo getApplicationInfo(Uri packageURI) {  
      
            final String archiveFilePath = packageURI.getPath();  
      
            PackageParser packageParser = new PackageParser(archiveFilePath);  
      
            File sourceFile = new File(archiveFilePath);  
      
            DisplayMetrics metrics = new DisplayMetrics();  
      
            metrics.setToDefaults();  
      
            PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);   
      
            if (pkg == null) {  
      
                    return null;  
      
            }     
      
            return pkg.applicationInfo;  
      
    }      
このアプリのパッケージ名を得ることができます。次の方法は方法と同じです。
 
 DexClassLoader dLoader = new DexClassLoader("/sdcard/download/test.apk","/sdcard/download",null,ClassLoader.getSystemClassLoader().getParent());  Class calledClass = dLoader.loadClass("com.test.classname");  Intent it=new Intent(this, calledClass);  it.setClassName("com.test", "com.test.classname");  startActivity(it);

 PathClassLoader:

 String packagePath = "com.mypackage"; String classPath = "com.mypackage.ExternalClass"; 

     String apkName = null;      try {      

    apkName = getPackageManager().getApplicationInfo(packagePath,0).sourceDir;   

   } catch (PackageManager.NameNotFoundException e) {          // catch this      }    

    // add path to apk that contains classes you wish to load   

   String extraApkPath = apkName + ":/path/to/extraLib.apk"       

  PathClassLoader pathClassLoader = new dalvik.system.PathClassLoader(        

      apkName,              ClassLoader.getSystemClassLoader());     

   try {    

      Class<?> handler = Class.forName(classPath, true, pathClassLoader);   

   } catch (ClassNotFoundException e) {     

     // catch this      }
 
.  SD   APK     ,      APK     , icon ,       : 
Java  
private void getUninatllApkInfo(Context context, String apkPath) {
  String PATH_PackageParser = "android.content.pm.PackageParser";
  String PATH_AssetManager = "android.content.res.AssetManager";
  try {
   // apk      
   //     Package    ,     
   //            , apk     
   // PackageParser packageParser = new PackageParser(apkPath);
   Class pkgParserCls = Class.forName(PATH_PackageParser);
   Class[] typeArgs = new Class[1];
   typeArgs[0] = String.class;
   Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs);
   Object[] valueArgs = new Object[1];
   valueArgs[0] = apkPath;
   Object pkgParser = pkgParserCt.newInstance(valueArgs);
   Log.d("ANDROID_LAB", "pkgParser:" + pkgParser.toString());
   //          ,              ,          
   DisplayMetrics metrics = new DisplayMetrics();
   metrics.setToDefaults();
   typeArgs = new Class[4];
   typeArgs[0] = File.class;
   typeArgs[1] = String.class;
   typeArgs[2] = DisplayMetrics.class;
   typeArgs[3] = Integer.TYPE;
   Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod(
     "parsePackage", typeArgs);
   valueArgs = new Object[4];
   valueArgs[0] = new File(apkPath);
   valueArgs[1] = apkPath;
   valueArgs[2] = metrics;
   valueArgs[3] = 0;
   Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,
     valueArgs);
   //        ,      ,       ,      
   // ApplicationInfo info = mPkgInfo.applicationInfo;
   Field appInfoFld = pkgParserPkg.getClass().getDeclaredField(
     "applicationInfo");
   ApplicationInfo info = (ApplicationInfo) appInfoFld
     .get(pkgParserPkg);
   // uid    "-1",      ,      Uid。
   Log
     .d("ANDROID_LAB", "pkg:" + info.packageName + " uid="
       + info.uid);
   Class assetMagCls = Class.forName(PATH_AssetManager);
   Constructor assetMagCt = assetMagCls.getConstructor((Class[]) null);
   Object assetMag = assetMagCt.newInstance((Object[]) null);
   typeArgs = new Class[1];
   typeArgs[0] = String.class;
   Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod(
     "addAssetPath", typeArgs);
   valueArgs = new Object[1];
   valueArgs[0] = apkPath;
   assetMag_addAssetPathMtd.invoke(assetMag, valueArgs);
   Resources res = context.getResources();
   typeArgs = new Class[3];
   typeArgs[0] = assetMag.getClass();
   typeArgs[1] = res.getDisplayMetrics().getClass();
   typeArgs[2] = res.getConfiguration().getClass();
   Constructor resCt = Resources.class.getConstructor(typeArgs);
   valueArgs = new Object[3];
   valueArgs[0] = assetMag;
   valueArgs[1] = res.getDisplayMetrics();
   valueArgs[2] = res.getConfiguration();
   res = (Resources) resCt.newInstance(valueArgs);
   CharSequence label = null;
   if (info.labelRes != 0) {
    label = res.getText(info.labelRes);
   }
   Log.d("ANDROID_LAB", "label=" + label);
   //         apk     
   if (info.icon != 0) {
    this.icon = res.getDrawable(info.icon);
    appName = label.toString();
    packageName = info.packageName;
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
iconはこのAPKのアイコンです。appNameはこのアプリの です。package Nameはこのアプリのパッケージ です。2. は、インストールされているすべての システムアプリのコードをどのように するかです。Javaコード
private ArrayList<InstalledAppInfo> getInstalledApps() {
  ArrayList<InstalledAppInfo> res = new ArrayList<InstalledAppInfo>();
  List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
  for (int i = 0; i < packs.size(); i++) {
   PackageInfo p = packs.get(i);
   if((p.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0){
    continue;
   }
   InstalledAppInfo newInfo = new InstalledAppInfo();
   newInfo.setAppname(p.applicationInfo.loadLabel(getPackageManager())
     .toString());
   newInfo.setPname(p.packageName);
   newInfo.setVersionName(p.versionName);
   newInfo.setVersionCode(p.versionCode);
   newInfo.setIcon(p.applicationInfo.loadIcon(getPackageManager()));
   res.add(newInfo);
  }
  return res;
 }
のうち、Javaコード
if((p.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0){
    continue;
   }
は、systemアプリをフィルタするために されます。
  ,         ,   api   apk      ?
Google      Api,          ,         //apk      
String apkPath = "/sdcard/qq.apk";
//    Package    ,     
//           , apk     
PackageParser packageParser = new PackageParser(apkPath);
//         ,              ,          
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
//       ,     , 
//   File, 
//      (            ,  Android     ,         ,      destFileName) 
//  , DisplayMetrics metrics
//flags,         
PackageParser.Package mPkgInfo = packageParser.parsePackage(new File(apkPath),
apkPath, metrics, 0);
//       ,      ,       ,      
ApplicationInfo info = mPkgInfo.applicationInfo;
//Resources          ,                 
//        ,     .
Resources pRes = getResources();
AssetManager assmgr = new AssetManager();
assmgr.addAssetPath(apkPath);
Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
CharSequence label = null;
if (info.labelRes != 0) {
try {
label = res.getText(info.labelRes);
} catch (Resources.NotFoundException e) {
}
}
if (label == null) {
label = (info.nonLocalizedLabel != null) ?
info.nonLocalizedLabel : info.packageName;
}
//        apk     
if (info.icon != 0){
Drawable icon = res.getDrawable(info.icon);
ImageView image = (ImageView) findViewById(R.id.iv_test);
image.setVisibility(View.VISIBLE);
image.setImageDrawable(icon);
}
}

, ( ) , 。APK Android Package , Android 。APK Symbian Sis Sisx 。 APK Android Android 。

Android

1.        ―― ,

2.        ―― market ,

3.        ADB ―― 。

4.        ―― SD APK , , packageinstaller.apk 。

system/app   ,   data/app   , 。

apk   data/data     Data/dalvik-cache   apk dex dalvik-cache (dex dalvik , apk )  

       : APK data/app , , dex (Dalvik ) dalvik-cache , data/data 。

       : 。

 

、 : PackageManagerService , , , systemServer

( :androidframeworksaseservicesjavacomandroidserverPackageManagerService.java)

PackageManagerService :

1. “systemframework” jar

1. scanDirLI(mFrameworkDir,PackageParser.PARSE_IS_SYSTEM,

                    scanMode | SCAN_NO_DEX);

2. “systemapp”

scanDirLI(mSystemAppDir,PackageParser.PARSE_IS_SYSTEM, scanMode);

3. “dataapp” ,

scanDirLI(mAppInstallDir, 0, scanMode);

4. " dataapp-private" , DRM APK ( )。

scanDirLI(mDrmAppPrivateInstallDir,0, scanMode | SCAN_FORWARD_LOCKED);

1.scanDirLI(Filedir, int flags, int scanMode)

2.scanPackageLI(FilescanFile,

            File destCodeFile, FiledestResourceFile, int parseFlags,

            int scanMode)                package

3.scanPackageLI(

        File scanFile, File destCodeFile, FiledestResourceFile,

        PackageParser.Package pkg, intparseFlags, int scanMode)

parsePackage

4.mInstaller.install(pkgName,pkg.applicationInfo.uid,

              pkg.applicationInfo.uid);  

( :frameworksasecmdsinstalldinstalld.install)

、 market : Google Market gmail , , , , , , Packagemanager , :

public voidinstallPackage(final Uri packageURI, final IPackageInstallObserver observer,final int flags)

final Uri packageURI:

final IPackageInstallObserver observer:

final int flags: , market , -r (replace)

installPackage :

1.public voidinstallPackage(

            final Uri packageURI, final IPackageInstallObserverobserver, final int flags,

            final String installerPackageName)

final StringinstallerPackageName: settings , null,

2.FiletmpPackageFile = copyTempInstallFile(packageURI, res);

apk

3.private voidinstallPackageLI(Uri pPackageURI,

            int pFlags, boolean newInstall,String installerPackageName,

           File tmpPackageFile, PackageInstalledInfo res)

, pkgName = PackageParser.parsePackageName(

                   tmpPackageFile.getAbsolutePath(), 0);

4. INSTALL_REPLACE_EXISTING, replacePackageLI(pkgName,

                        tmpPackageFile,

                        destFilePath,destPackageFile, destResourceFile,

                        pkg, forwardLocked,newInstall, installerPackageName,

                        res)

5. , installNewPackageLI(pkgName,

                        tmpPackageFile,

                        destFilePath,destPackageFile, destResourceFile,

                        pkg,forwardLocked, newInstall, installerPackageName,

                        res);

6.privatePackageParser.Package scanPackageLI(

        File scanFile, File destCodeFile, FiledestResourceFile,

        PackageParser.Package pkg, intparseFlags, int scanMode)

scanPackageLI , 。

、 ADB Android Debug Bridge (adb) SDK , ADB , pm.java

( :androidframeworksasecmdspmsrccomandroidcommandspmpm.java)

ADB adb install <path_to_apk> , :"-l""-r" "-i" "-t"

runInstall()

"-l"――INSTALL_FORWARD_LOCK

 "-r"——INSTALL_REPLACE_EXISTING 

"-i" ——installerPackageName

"-t"——INSTALL_ALLOW_TEST

-r, 。 market , 。

runInstall market 。

public voidinstallPackage(android.net.Uri packageURI,android.content.pm.IPackageInstallObserver observer, int flags,java.lang.String installerPackageName)

、 ―― SD APK APK SD , SD APK , , Packageinstaller.apk , :

PackageInstallerActivity , Apk

/data/data/com.android.packageinstaller/files/ApiDemos.apk

startInstallConfirm, 。 , 。

, InstallAppProgress, 。

pm.installPackage(mPackageURI,observer, installFlags);

: 1. PackageManagerService.java AppDirObserver app : APK app , scanPackageLI 。

2. “data/system/packages.xml” , , , permission 。