/**
* @return all local plaugins
*/
private List<PlauginInfo> findLocalPlugins(){
PackageManager pm=getPackageManager();
//List<PackageInfo> pkgs=pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
Intent mainIntent = new Intent("com.android.uxun", null);
List<ResolveInfo> allApps=getPackageManager().queryIntentActivities(mainIntent, 0);
Log.i(TAG, "======allApps.size()==="+allApps.size());
sLoaclPlugins.clear();
for(ResolveInfo resolveInfo:allApps){
String packageName=resolveInfo.activityInfo.packageName;
ApplicationInfo applicationInfo=resolveInfo.activityInfo.applicationInfo;
String label=pm.getApplicationLabel(applicationInfo).toString();
PlauginInfo plug=new PlauginInfo();
Context context=null;
try {
context = createPackageContext(packageName,Context.CONTEXT_IGNORE_SECURITY);
if(context!=null){
plug.classId=context.getSharedPreferences("plaugin",MODE_WORLD_READABLE+MODE_WORLD_WRITEABLE).getInt("plauginId",0);
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
plug.description="";
Drawable drawable=pm.getApplicationIcon(applicationInfo);
if(drawable!=null){
plug.icon=((BitmapDrawable)drawable).getBitmap();
}
plug.intent=new Intent(packageName);
plug.itemType=0;
plug.openCount=0;
plug.postFlag=0;
plug.title=label;
int versionCode=0;
try {
versionCode = pm.getPackageInfo(packageName,0).versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
plug.versionId=versionCode;
sLoaclPlugins.add(plug);
}
/*for(PackageInfo pkg:pkgs){
if("android.uxun".equals(pkg.sharedUserId)){
String packageName=pkg.packageName;
//String prcessName=pkg.applicationInfo.processName;
String label=pm.getApplicationLabel(pkg.applicationInfo).toString();
PlauginInfo plug=new PlauginInfo();
Context context=null;
try {
context = createPackageContext(packageName,Context.CONTEXT_IGNORE_SECURITY);
if(context!=null){
plug.classId=context.getSharedPreferences("plaugin",MODE_WORLD_READABLE+MODE_WORLD_WRITEABLE).getInt("plauginId",0);
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
plug.description="";
Drawable drawable=pm.getApplicationIcon(pkg.applicationInfo);
if(drawable!=null){
plug.icon=((BitmapDrawable)drawable).getBitmap();
}
plug.intent=new Intent(packageName);
plug.itemType=0;
plug.openCount=0;
plug.postFlag=0;
plug.title=label;
plug.versionId=pkg.versionCode;
sLoaclPlugins.add(plug);
}
}*/
return sLoaclPlugins;
} 前提条件是需要系统编译生成的class.jar文件 ** *Utilitymethodtogetdefaulticonforagivenpackage *@paramarchiveFilePaththeabsolutepathofthepackage *@returntheDrawableobjectofthepackage */ public DrawablegetIconFromPackage(StringarchiveFilePath){ PackageParserpackageParser= new PackageParser(archiveFilePath); FilesourceFile= new File(archiveFilePath); DisplayMetricsmetrics= new DisplayMetrics(); metrics.setToDefaults(); PackageParser.Packagepkg=packageParser.parsePackage(sourceFile, archiveFilePath,metrics, 0 ); if (pkg== null ) return mContext.getResources().getDrawable(R.drawable.android); ApplicationInfoinfo=pkg.applicationInfo; ResourcespRes=mContext.getResources(); AssetManagerassmgr= new AssetManager(); assmgr.addAssetPath(archiveFilePath); Resourcesres= new Resources(assmgr,pRes.getDisplayMetrics(), pRes.getConfiguration()); //readthedeafulticonofthepackage if (info.icon!= 0 ){ Drawableicon=res.getDrawable(info.icon); return icon; } else { return mContext.getResources().getDrawable(R.drawable.android); } } 一个apk读取另一个apk资源(前提条件是两个apk为同一个进程 主程序及要 读取的apk中AndroidManifest.xml中配置 例如:android:sharedUserId="com.android.main.chajian" //主apk的包名 ) <?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();
}
} 次apk================================ <?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。次apk的配置文件android:sharedUserId="com.android.main.chajian"//主apk的包名 3。com.android.main.chajian在主apk和次apk中都要有定义,而且是路径要相同 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; } 方法一:最直接的就是知道apk的包名和启动类名, 直接启动 [java] view plain copy
  1. IntentmIntent=newIntent();
  2. ComponentNamecomp=newComponentName("包名","类名");
  3. mIntent.setComponent(comp);
  4. mIntent.setAction("android.intent.action.VIEW");
  5. startActivity(mIntent);

方法二:如果只知道包名,在这种情况下通常也可以启动,通常调用 publicabstract Intent getLaunchIntentForPackage(String packageName) 大概意思就是返回一个程序入口的Intent,就是Java程序的Main方法。直接startActivity(返回的intent)即可。
Intent mIntent = getPackageManager() getLaunchIntentForPackage(packageName); if( mIntent != null ) startActivity(mIntent);

方法三:就是如何只提供apk,如何启动呢?在这种情况下,通常只能在sdk源代码下来编译完成
通常引入android.content.pm.PackageParser;
见code:
[java] view plain copy
  1. /*
  2. *UtilitymethodtogetapplicationinformationforagivenpackageURI
  3. */
  4. publicApplicationInfogetApplicationInfo(UripackageURI){
  5. finalStringarchiveFilePath=packageURI.getPath();
  6. PackageParserpackageParser=newPackageParser(archiveFilePath);
  7. FilesourceFile=newFile(archiveFilePath);
  8. DisplayMetricsmetrics=newDisplayMetrics();
  9. metrics.setToDefaults();
  10. PackageParser.Packagepkg=packageParser.parsePackage(sourceFile,archiveFilePath,metrics,0);
  11. if(pkg==null){
  12. returnnull;
  13. }
  14. returnpkg.applicationInfo;
  15. }

这样就可以得到该apk的包名,接下来方式就和方法二一样则可
 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就是这个apk的名称,packageName就是这个apk的包名。
2.下面是如何获取所有的已经安装的非系统app的代码:
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 app。
好了, 虽然我们不能安装, 但用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. 系统应用安装�D�D开机时完成,没有安装界面                                                                            2. 网络下载应用安装�D�D通过market应用完成,没有安装界面                                                                            3. ADB工具安装�D�D没有安装界面。                                                                            4. 第三方应用安装�D�D通过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"�D�DINSTALL_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)                                                                            四、第三方应用安装�D�D通过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等信息。                        

更多相关文章

  1. Pycharm安装PyQt5的详细教程
  2. NPM 和webpack 的基础使用
  3. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  4. android 文件系统分析
  5. Android(安卓)SDcard 文件读写,RandomAccessFile操作
  6. android加载.swf flash文件
  7. Android(安卓)App应用底部导航栏实现的一种方式
  8. android Error inflating class com.google.android.material.ch
  9. android根据应用方向自动旋转的自定义view

随机推荐

  1. Android(安卓)---模拟手机发送短信
  2. Android中触摸事件MotionEvent的来源
  3. Android(安卓)Design Support Library 介
  4. android 和h5互调步骤
  5. ArchLinux安装Android(安卓)Studio出现的
  6. Android多线程研究(1)——线程基础及源码剖
  7. TextView 文本过长时自动打点
  8. Android(安卓)Butter Knife使用说明
  9. Android获取View的内容图片
  10. android 视频播放 JiaoZiVideoPlayer使用