以下片段收集自: http://blog.csdn.net/zhangjg_blog/article/details/27697665
不能保证代码片段没有bug, 在使用时需要经过测试.
1 切换系统中某个组件的状态,设置其enable或disable
- public void toggleComponent(View view){
- PackageManager pm = getPackageManager();
- String pkgName = "com.aa.activitytest";
- String comName = "com.aa.activitytest.SecondActivity";
- ComponentName componentName = new ComponentName(pkgName, comName);
- int state = pm.getComponentEnabledSetting(componentName);
- boolean isEnable = state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
- || state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
- if(isEnable){
- pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
- }else {
- pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
- }
- }
2 列出系统中所有安装的app的信息
- PackageManager pm = getPackageManager();
- List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
- for(PackageInfo packageInfo : packages){
- //应用图标
- Drawable icon = packageInfo.applicationInfo.loadIcon(pm);
- //标题
- CharSequence lable = packageInfo.applicationInfo.loadLabel(pm);
- //包名
- String packageName = packageInfo.packageName;
- }
3 将raw中的apk拷贝到/data/data/包名/files/中
- //1 拷贝raw中的apk文件
- InputStream in = null;
- OutputStream out = null;
- try {
- in = getResources().openRawResource(R.raw.dex_apk);
- out = this.openFileOutput("dex_apk.apk", Context.MODE_PRIVATE);
- copyFile(in, out);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }finally {
- try {
- if (in != null) in.close();
- }catch (IOException e){}
- try{
- if (out != null) out.close();
- }catch (IOException e){}
- }
4 拷贝文件
- private void copyFile(InputStream in, OutputStream out){
- byte[] buffer = new byte[1024];
- int len = 0;
- try {
- while((len = in.read(buffer) ) != -1){
- out.write(buffer , 0 , len);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
5 使用DexClassLoader加载 /data/data/包名/files/ 下的apk的classes.dex , 并通过反射执行。
- //2 加载并执行apk中的类
- String pkgDataPath = "/data/data/" + getPackageName();
- String optimizedDirectory = pkgDataPath + "/files/";
- String dexPath = optimizedDirectory + "dex_apk.apk";
- DexClassLoader dexClassLoader = new DexClassLoader(dexPath, optimizedDirectory, null, this.getClassLoader());
- try {
- Class personClazz = dexClassLoader.loadClass("com.aa.dexapk.Person");
- Object newInstance = personClazz.newInstance();
- Method method = personClazz.getMethod("doWork");
- method.invoke(newInstance);
- } catch (Exception e) {
- e.printStackTrace();
- }
6 动态加载其他已经安装的apk的dex文件, 并通过反射执行
- private void useDexClassLoader(){
- //创建一个意图,用来找到指定的apk
- Intent intent = new Intent("com.suchangli.android.plugin", null);
- //获得包管理器
- PackageManager pm = getPackageManager();
- List<ResolveInfo> resolveinfoes = pm.queryIntentActivities(intent, 0);
- //获得指定的activity的信息
- ActivityInfo actInfo = resolveinfoes.get(0).activityInfo;
- //获得包名
- String pacageName = actInfo.packageName;
- //获得apk的目录或者jar的目录
- String apkPath = actInfo.applicationInfo.sourceDir;
- //dex解压后的目录,注意,这个用宿主程序的目录,android中只允许程序读取写自己
- //目录下的文件
- String dexOutputDir = getApplicationInfo().dataDir;
- //native代码的目录
- String libPath = actInfo.applicationInfo.nativeLibraryDir;
- //创建类加载器,把dex加载到虚拟机中
- DexClassLoader calssLoader = new DexClassLoader(apkPath, dexOutputDir, libPath,
- this.getClass().getClassLoader());
- //利用反射调用插件包内的类的方法
- try {
- Class<?> clazz = calssLoader.loadClass(pacageName+".Plugin1");
- Object obj = clazz.newInstance();
- Class[] param = new Class[2];
- param[0] = Integer.TYPE;
- param[1] = Integer.TYPE;
- Method method = clazz.getMethod("function1", param);
- Integer ret = (Integer)method.invoke(obj, 1,12);
- Log.i("Host", "return result is " + ret);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
7 获取其他包中的资源(pm.getResourcesForApplication(pkgName) )
- Intent intent = new Intent("com.suchangli.android.plugin", null);
- //获得包管理器
- PackageManager pm = getPackageManager();
- List<ResolveInfo> resolveinfoes = pm.queryIntentActivities(intent, 0);
- //获得指定的activity的信息
- ActivityInfo actInfo = resolveinfoes.get(0).activityInfo;
- //获得包名
- String pacageName = actInfo.packageName;
- try {
- Resources res = pm.getResourcesForApplication(pacageName);
- int id = 0;
- id = res.getIdentifier("ic_launcher", "drawable", pacageName);
- Log.i("", "resId is " + id);
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- }
8 Context.getDir创建并返回目录
Context.getDir(“mydir”) 返回的目录的绝对路径是 : /data/data/package_name/app_mydir 。
9 获取Activity的图标
- private Bitmap getIconForActivity(Context context, String packageName, String activityName){
- ComponentName activityComp = new ComponentName(packageName, activityName);
- PackageManager pm = context.getPackageManager();
- Intent intentToResolve = new Intent();
- intentToResolve.setComponent(activityComp);
- ResolveInfo resolveInfo = pm.resolveActivity(intentToResolve, 0);
- Drawable iconDrawable = resolveInfo.activityInfo.loadIcon(pm);
- return Utilities.createIconBitmap( iconDrawable, context);
- }
其中Utilities为Launcher中的工具类。
10 获取当前app的签名信息:
- /**
- * get signature of current package
- * @param context
- * @return signature, null if there is no signature
- */
- public static String getSignature(Context context){
- Log.i(TAG, "SignatureUtils.getSignature");
- PackageManager pm = context.getPackageManager();
- String pkgName = context.getPackageName();
- try {
- PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
- Signature[] signatures = pi.signatures;
- if(signatures != null && signatures.length > 0){
- String signature = signatures[0].toCharsString();
- Log.i(TAG, "Signature of current package is : " + signature);
- return signature;
- }
- } catch (PackageManager.NameNotFoundException e1) {
- e1.printStackTrace();
- }
- return null;
- }
11 获取apk文件的签名信息(未安装, 只是一个apk文件)
- /**
- * get signature of an apk file
- * this method will execute quit a long time, so it is suitable to call it in sub thread
- * @param context
- * @param apkFilePath
- * @return signature , null if there is no signature , or apkFilePath is wrong
- */
- public static String getSignatureOfApk(Context context, String apkFilePath){
- Log.i(TAG, "SignatureUtils.getSignatureOfApk");
- if (TextUtils.isEmpty(apkFilePath)) return null;
- PackageManager pm = context.getPackageManager();
- PackageInfo pi = pm.getPackageArchiveInfo(apkFilePath, PackageManager.GET_SIGNATURES);
- Signature[] signatures = pi.signatures;
- if(signatures != null && signatures.length > 0){
- String signature = signatures[0].toCharsString();
- Log.i(TAG, "Signature of " + apkFilePath + " is : " + signature);
- return signature;
- }
- return null;
- }
12 获取apk文件的权限信息
- public static List<PermissionInfo> getApkPermissions(String apkFile, PackageManager pm){
- if(DEBUG) Log.i(TAG, "PackageUtils.getApkPermissions");
- List<PermissionInfo> permissionInfos = new ArrayList<PermissionInfo>();
- PackageInfo packageInfo = pm.getPackageArchiveInfo(apkFile, PackageManager.GET_PERMISSIONS);
- String[] permissions = packageInfo.requestedPermissions;
- for(String permName : permissions ){
- try {
- PermissionInfo permissionInfo = pm.getPermissionInfo(permName, 0);
- permissionInfos.add(permissionInfo);
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- }
- return permissionInfos;