Android:利用Java反射调用@hide的API

时间:2014-05-09 09:39:28   收藏:0   阅读:711

置使用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

Android:利用Java反射调用@hide的API,布布扣,bubuko.com

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!