Android:利用Java反射调用@hide的API
2013-01-04 23:11
525 查看
设置使用3G数据功能:
从源代码看到隐藏的API(ConnectivityManager.java):
通过java reflection功能来实现该功能,即调用
代码如下:
注意添加相应的permission:
补充一个网上利用java reflection解析APK软件包信息的代码:
从源代码看到隐藏的API(ConnectivityManager.java):
/** * Sets the persisted value for enabling/disabling Mobile data. * * @param enabled Whether the mobile data connection should be * used or not. * @hide */ public void setMobileDataEnabled(boolean enabled) { try { mService.setMobileDataEnabled(enabled); } catch (RemoteException e) { } }
通过java reflection功能来实现该功能,即调用
mService.setMobileDataEnabled(enabled);
代码如下:
private void EnableMobileData(boolean enable) { ConnectivityManager connectivitymanager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); try { // Get mService // android.net.ConnectivityManager.mService; Field field = Class.forName(ConnectivityManager.class.getName()) .getDeclaredField("mService"); field.setAccessible(true); /* // 权限修饰符 int mo = field.getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = field.getType(); Log.i(TAG, priv + " " + type.getName() + " " + field.getName() + ";"); */ // get Object of mService Object obj = field.get(connectivitymanager);// connectivitymanager.mService // get IConnectivityManager class Class myClass = Class.forName(obj.getClass().getName()); Log.i(TAG, "class3:" + obj.getClass().getName());// IConnectivityManager // get android.net.IConnectivityManager // public void setMobileDataEnabled(boolean enabled) throws // android.os.RemoteException; Method method = myClass.getDeclaredMethod("setMobileDataEnabled", boolean.class); /* String pstr = ""; Class<?>[] parameters = method.getParameterTypes(); int count = parameters.length; Log.i(TAG, "count:" + count); if (count > 0) { for (Class<?> p : parameters) { pstr += p.getName() + ","; } pstr = pstr.substring(0, pstr.length() - 1); Log.i(TAG, "pstr:" + pstr); } Log.i(TAG, Modifier.toString(method.getModifiers()) + " " + method.getReturnType().getName() + " " + method.getName() + "(" + pstr + ");"); */ method.setAccessible(true); method.invoke(obj, enable); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
注意添加相应的permission:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
补充一个网上利用java reflection解析APK软件包信息的代码:
// Ref:http://blog.csdn.net/sodino/article/details/6215224 // 利用反射机制调用android @hide的API进行解析 public static void ExtractApkInfoExt(String apkPath, DownloadTask task) { String PATH_PackageParser = "android.content.pm.PackageParser"; String PATH_AssetManager = "android.content.res.AssetManager"; try { // apk包的文件路径 // 这是一个Package 解释器, 是隐藏的 // 构造函数的参数只有一个, apk文件的路径 // PackageParser packageParser = new PackageParser(apkPath); Class pkgParserCls = Class.forName(PATH_PackageParser); Class[] typeArgs = new Class[1]; typeArgs[0] = String.class; Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs); Object[] valueArgs = new Object[1]; valueArgs[0] = apkPath; Object pkgParser = pkgParserCt.newInstance(valueArgs); if (Constants.DEBUG_MODE) Log.d(TAG, "pkgParser:" + pkgParser.toString()); // 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况 DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); // PackageParser.Package mPkgInfo = packageParser.parsePackage(new // File(apkPath), apkPath, // metrics, 0); typeArgs = new Class[4]; typeArgs[0] = File.class; typeArgs[1] = String.class; typeArgs[2] = DisplayMetrics.class; typeArgs[3] = Integer.TYPE; Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod( "parsePackage", typeArgs); valueArgs = new Object[4]; valueArgs[0] = new File(apkPath); valueArgs[1] = apkPath; valueArgs[2] = metrics; valueArgs[3] = 0; Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs); if (pkgParserPkg == null) { return; } // 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开 // ApplicationInfo info = mPkgInfo.applicationInfo; Field appInfoFld = pkgParserPkg.getClass().getDeclaredField( "applicationInfo"); ApplicationInfo info = (ApplicationInfo) appInfoFld .get(pkgParserPkg); // get VersionCode Field versionCodeFld = pkgParserPkg.getClass().getDeclaredField( "mVersionCode"); int versionCode = ((Integer) versionCodeFld.get(pkgParserPkg)) .intValue(); // get VersionName Field versionNameFld = pkgParserPkg.getClass().getDeclaredField( "mVersionName"); String versionName = (String) versionNameFld.get(pkgParserPkg); // uid 输出为"-1",原因是未安装,系统未分配其Uid。 if (Constants.DEBUG_MODE) Log.d(TAG, "pkg:" + info.packageName + " uid=" + info.uid); // Resources pRes = getResources(); // AssetManager assmgr = new AssetManager(); // assmgr.addAssetPath(apkPath); // Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), // pRes.getConfiguration()); Class assetMagCls = Class.forName(PATH_AssetManager); Constructor assetMagCt = assetMagCls.getConstructor((Class[]) null); Object assetMag = assetMagCt.newInstance((Object[]) null); typeArgs = new Class[1]; typeArgs[0] = String.class; Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod( "addAssetPath", typeArgs); valueArgs = new Object[1]; valueArgs[0] = apkPath; assetMag_addAssetPathMtd.invoke(assetMag, valueArgs); Resources res = mContext.getResources(); typeArgs = new Class[3]; typeArgs[0] = assetMag.getClass(); typeArgs[1] = res.getDisplayMetrics().getClass(); typeArgs[2] = res.getConfiguration().getClass(); Constructor resCt = Resources.class.getConstructor(typeArgs); valueArgs = new Object[3]; valueArgs[0] = assetMag; valueArgs[1] = res.getDisplayMetrics(); valueArgs[2] = res.getConfiguration(); res = (Resources) resCt.newInstance(valueArgs); CharSequence label = null; if (info.labelRes != 0) { label = res.getText(info.labelRes); // if (label == null) { // label = (info.nonLocalizedLabel != null) ? // info.nonLocalizedLabel // : info.packageName; // } task.setTitle(String.valueOf(label)); } if (Constants.DEBUG_MODE) Log.d(TAG, "label=" + label); // 这里就是读取一个apk程序的图标 if (info.icon != 0) { Drawable icon = res.getDrawable(info.icon); task.setIcon(((BitmapDrawable) icon).getBitmap()); // ImageView image = (ImageView) findViewById(R.id.appicon); // image.setVisibility(View.VISIBLE); // image.setImageDrawable(icon); } if (versionName != null) { task.setVersionName(versionName); } task.setVersionCode(versionCode); task.setPackageName(info.packageName); if (info.processName == null) { info.processName = info.packageName; } task.setProcessName(info.processName); } catch (Exception e) { e.printStackTrace(); } }
相关文章推荐
- Android:利用Java反射调用@hide的API
- 利用Java反射技术调用Android中被隐藏的API
- [Android] 利用java反射调用隐藏Api
- android 应用开发,利用反射机制调用非官方api
- android学习日记:利用反射调用隐藏API
- Android利用反射调用影藏API
- Android学习——利用反射调用@Hide隐藏函数
- Android学习——利用反射调用@Hide隐藏函数
- 利用java反射解决 Android系统方法不能调用的情况
- 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!
- Android 反射调用方法并利用此方法展开android通知栏(兼容4.2及以上)
- java中利用反射调用另一类的private方法的简单实例
- 【Android开发经验】利用反射机制,获取类的字段、方法、并实现简单调用
- android中利用java反射原理将对象添加到sqlit数据库的万能方法
- 利用java反射调用实现对字符串的解析,成功调入函数,并且返回值
- Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框
- android编译内置应用以及调用隐藏API(@hide)
- Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框
- java利用反射来调用一个类的私有方法和成员变量
- 比FastMethod更快的Java反射调用API,以及比Cglib更快的BeanMap实现