Android开发代码片段积累(一)

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



你可能感兴趣的:(android,代码片段,APP开发)