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);
}
return sLoaclPlugins;
}
前提条件是需要系统编译生成的class.jar文件
** * Utility method to get default icon for a given package * @param archiveFilePath the absolute path of the package * @return the Drawable object of 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);
}
}
一个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 {
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 {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
===========================================================================
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); //