本博客积累Android开发中常用的代码片段, 如果用到的话, 可以直接拿来用. 以后可以考虑将这些代码片段封装成组件或工具类. 不能保证代码片段没有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){} }
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(); } }
//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); }
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; }