您的位置:首页 > 移动开发 > Android开发

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

2013-01-04 23:11 525 查看
设置使用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
// 利用反射机制调用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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: