androidは他のアプリの情報を取得します。
前提条件は、システムコンパイルで生成されたクラス.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 。