本博客积累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){}
}
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;
}