Android:利用Java反射调用@hide的API
时间:2014-05-09 09:39:28
收藏:0
阅读:711
置使用3G数据功能:
从源代码看到隐藏的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
- // <strong>利用</strong><strong>反射</strong>机制<strong>调用</strong>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();
- }
- }
评论(0)