zoukankan      html  css  js  c++  java
  • Android:利用Java反射调用@hide的API

    置使用3G数据功能:

    从源代码看到隐藏的API(ConnectivityManager.java):

     

    1. /** 
    2.     * Sets the persisted value for enabling/disabling Mobile data. 
    3.     * 
    4.     * @param enabled Whether the mobile data connection should be 
    5.     *            used or not. 
    6.     * @hide 
    7.     */  
    8.    public void setMobileDataEnabled(boolean enabled) {  
    9.        try {  
    10.            mService.setMobileDataEnabled(enabled);  
    11.        } catch (RemoteException e) {  
    12.        }  
    13.    }  


    通过java reflection功能来实现该功能,即调用

    1. mService.setMobileDataEnabled(enabled);  

     

    代码如下:

     

    1. private void EnableMobileData(boolean enable)  
    2.     {  
    3.         ConnectivityManager connectivitymanager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);  
    4.   
    5.         try  
    6.         {  
    7.             // Get mService  
    8.             // android.net.ConnectivityManager.mService;  
    9.             Field field = Class.forName(ConnectivityManager.class.getName())  
    10.                     .getDeclaredField("mService");  
    11.             field.setAccessible(true);  
    12.             /* 
    13.             // 权限修饰符 
    14.             int mo = field.getModifiers(); 
    15.             String priv = Modifier.toString(mo); 
    16.             // 属性类型 
    17.             Class<?> type = field.getType(); 
    18.             Log.i(TAG, priv + " " + type.getName() + " " + field.getName() 
    19.                     + ";"); 
    20.             */  
    21.             // get Object of mService  
    22.             Object obj = field.get(connectivitymanager);// connectivitymanager.mService  
    23.             // get IConnectivityManager class  
    24.             Class myClass = Class.forName(obj.getClass().getName());  
    25.             Log.i(TAG, "class3:" + obj.getClass().getName());// IConnectivityManager  
    26.             // get android.net.IConnectivityManager  
    27.             // public void setMobileDataEnabled(boolean enabled) throws  
    28.             // android.os.RemoteException;  
    29.             Method method = myClass.getDeclaredMethod("setMobileDataEnabled",  
    30.                     boolean.class);  
    31.   
    32.             /* 
    33.             String pstr = ""; 
    34.             Class<?>[] parameters = method.getParameterTypes(); 
    35.             int count = parameters.length; 
    36.             Log.i(TAG, "count:" + count); 
    37.             if (count > 0) 
    38.             { 
    39.                 for (Class<?> p : parameters) 
    40.                 { 
    41.                     pstr += p.getName() + ","; 
    42.                 } 
    43.                 pstr = pstr.substring(0, pstr.length() - 1); 
    44.                 Log.i(TAG, "pstr:" + pstr); 
    45.             } 
    46.             Log.i(TAG, Modifier.toString(method.getModifiers()) + " " 
    47.                     + method.getReturnType().getName() + " " + method.getName() 
    48.                     + "(" + pstr + ");"); 
    49.             */  
    50.             method.setAccessible(true);  
    51.             method.invoke(obj, enable);  
    52.   
    53.         }  
    54.         catch (Exception e)  
    55.         {  
    56.             // TODO Auto-generated catch block  
    57.             e.printStackTrace();  
    58.         }  
    59.   
    60.     }  

     

    注意添加相应的permission:

     

    1. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
    2.   <uses-permission android:name="android.permission.INTERNET" />  
    3.  <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />  

     

     

    补充一个网上利用java reflection解析APK软件包信息的代码:

     

      1. // Ref:http://blog.csdn.net/sodino/article/details/6215224  
      2.     // <strong>利用</strong><strong>反射</strong>机制<strong>调用</strong>android @hide的API进行解析  
      3.     public static void ExtractApkInfoExt(String apkPath, DownloadTask task)  
      4.     {  
      5.         String PATH_PackageParser = "android.content.pm.PackageParser";  
      6.         String PATH_AssetManager = "android.content.res.AssetManager";  
      7.         try  
      8.         {  
      9.             // apk包的文件路径  
      10.             // 这是一个Package 解释器, 是隐藏的  
      11.             // 构造函数的参数只有一个, apk文件的路径  
      12.             // PackageParser packageParser = new PackageParser(apkPath);  
      13.             Class pkgParserCls = Class.forName(PATH_PackageParser);  
      14.             Class[] typeArgs = new Class[1];  
      15.             typeArgs[0] = String.class;  
      16.             Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs);  
      17.             Object[] valueArgs = new Object[1];  
      18.             valueArgs[0] = apkPath;  
      19.             Object pkgParser = pkgParserCt.newInstance(valueArgs);  
      20.             if (Constants.DEBUG_MODE)  
      21.                 Log.d(TAG, "pkgParser:" + pkgParser.toString());  
      22.             // 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况  
      23.             DisplayMetrics metrics = new DisplayMetrics();  
      24.             metrics.setToDefaults();  
      25.             // PackageParser.Package mPkgInfo = packageParser.parsePackage(new  
      26.             // File(apkPath), apkPath,  
      27.             // metrics, 0);  
      28.             typeArgs = new Class[4];  
      29.             typeArgs[0] = File.class;  
      30.             typeArgs[1] = String.class;  
      31.             typeArgs[2] = DisplayMetrics.class;  
      32.             typeArgs[3] = Integer.TYPE;  
      33.             Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod(  
      34.                     "parsePackage", typeArgs);  
      35.             valueArgs = new Object[4];  
      36.             valueArgs[0] = new File(apkPath);  
      37.             valueArgs[1] = apkPath;  
      38.             valueArgs[2] = metrics;  
      39.             valueArgs[3] = 0;  
      40.             Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,  
      41.                     valueArgs);  
      42.             if (pkgParserPkg == null)  
      43.             {  
      44.                 return;  
      45.             }  
      46.             // 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开  
      47.             // ApplicationInfo info = mPkgInfo.applicationInfo;  
      48.             Field appInfoFld = pkgParserPkg.getClass().getDeclaredField(  
      49.                     "applicationInfo");  
      50.             ApplicationInfo info = (ApplicationInfo) appInfoFld  
      51.                     .get(pkgParserPkg);  
      52.   
      53.             // get VersionCode  
      54.             Field versionCodeFld = pkgParserPkg.getClass().getDeclaredField(  
      55.                     "mVersionCode");  
      56.             int versionCode = ((Integer) versionCodeFld.get(pkgParserPkg))  
      57.                     .intValue();  
      58.   
      59.             // get VersionName  
      60.             Field versionNameFld = pkgParserPkg.getClass().getDeclaredField(  
      61.                     "mVersionName");  
      62.   
      63.             String versionName = (String) versionNameFld.get(pkgParserPkg);  
      64.   
      65.             // uid 输出为"-1",原因是未安装,系统未分配其Uid。  
      66.             if (Constants.DEBUG_MODE)  
      67.                 Log.d(TAG, "pkg:" + info.packageName + " uid=" + info.uid);  
      68.             // Resources pRes = getResources();  
      69.             // AssetManager assmgr = new AssetManager();  
      70.             // assmgr.addAssetPath(apkPath);  
      71.             // Resources res = new Resources(assmgr, pRes.getDisplayMetrics(),  
      72.             // pRes.getConfiguration());  
      73.   
      74.             Class assetMagCls = Class.forName(PATH_AssetManager);  
      75.             Constructor assetMagCt = assetMagCls.getConstructor((Class[]) null);  
      76.             Object assetMag = assetMagCt.newInstance((Object[]) null);  
      77.             typeArgs = new Class[1];  
      78.             typeArgs[0] = String.class;  
      79.             Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod(  
      80.                     "addAssetPath", typeArgs);  
      81.             valueArgs = new Object[1];  
      82.             valueArgs[0] = apkPath;  
      83.             assetMag_addAssetPathMtd.invoke(assetMag, valueArgs);  
      84.             Resources res = mContext.getResources();  
      85.             typeArgs = new Class[3];  
      86.             typeArgs[0] = assetMag.getClass();  
      87.             typeArgs[1] = res.getDisplayMetrics().getClass();  
      88.             typeArgs[2] = res.getConfiguration().getClass();  
      89.             Constructor resCt = Resources.class.getConstructor(typeArgs);  
      90.             valueArgs = new Object[3];  
      91.             valueArgs[0] = assetMag;  
      92.             valueArgs[1] = res.getDisplayMetrics();  
      93.             valueArgs[2] = res.getConfiguration();  
      94.             res = (Resources) resCt.newInstance(valueArgs);  
      95.             CharSequence label = null;  
      96.             if (info.labelRes != 0)  
      97.             {  
      98.                 label = res.getText(info.labelRes);  
      99.                 // if (label == null) {  
      100.                 // label = (info.nonLocalizedLabel != null) ?  
      101.                 // info.nonLocalizedLabel  
      102.                 // : info.packageName;  
      103.                 // }  
      104.                 task.setTitle(String.valueOf(label));  
      105.             }  
      106.   
      107.             if (Constants.DEBUG_MODE)  
      108.                 Log.d(TAG, "label=" + label);  
      109.             // 这里就是读取一个apk程序的图标  
      110.             if (info.icon != 0)  
      111.             {  
      112.                 Drawable icon = res.getDrawable(info.icon);  
      113.                 task.setIcon(((BitmapDrawable) icon).getBitmap());  
      114.                 // ImageView image = (ImageView) findViewById(R.id.appicon);  
      115.                 // image.setVisibility(View.VISIBLE);  
      116.                 // image.setImageDrawable(icon);  
      117.             }  
      118.             if (versionName != null)  
      119.             {  
      120.                 task.setVersionName(versionName);  
      121.             }  
      122.             task.setVersionCode(versionCode);  
      123.             task.setPackageName(info.packageName);  
      124.             if (info.processName == null)  
      125.             {  
      126.                 info.processName = info.packageName;  
      127.             }  
      128.             task.setProcessName(info.processName);  
      129.         }  
      130.         catch (Exception e)  
      131.         {  
      132.             e.printStackTrace();  
      133.         }  
      134.     }  

     

    原文:http://www.verydemo.com/demo_c89_i35812.html

  • 相关阅读:
    关于Git学习-远程库(github) 命令
    关于git的学习
    python-自动化测试结果发送邮件报错(smtplib.SMTPDataError: (554, b'DT:SPM 163……)解决方法
    android SDK- 使用 AVD Manager.exe 创建虚拟机遇到报错 emulator
    性能测试方案大纲-学习笔记
    python + locust 记录一次性能测试的实施
    jmeter 做压测常见问题记录-单台测试机建议最大线程数
    jmeter 调用mysql数据库,使用JDBC请求执行相关SQL
    加解密原理
    SM1,SM2,SM3,SM4刨析
  • 原文地址:https://www.cnblogs.com/veins/p/3717630.html
Copyright © 2011-2022 走看看