问题
i'm trying to use the method setMobileDataEnabled of the ConnectivityManager class, using SDK 2.2. According to http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2.1_r1/android/net/ConnectivityManager.java/?v=source this method is declared public but with @hide is not available in the SDK and in Eclipse.
In order to bypass the hiding I wrote the following function to toggle the mobile data connection on/off.
public void setMobileData(boolean toBeEnabled){
Object myObj= getSystemService(CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) myObj;
Class c = null;
try {
c = Class.forName(cm.getClass().getName());
} catch (ClassNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
Method m = null;
try {
m = c.getDeclaredMethod("getMobileDataEnabled");
} catch (SecurityException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (NoSuchMethodException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
Object mobileDataEnabled=null;
if (m!=null){
m.setAccessible(true);
Type res_of_m= m.getGenericReturnType();
Type[] pars_of_m= m.getGenericParameterTypes();
try {
mobileDataEnabled = (m.invoke(cm));
if (mobileDataEnabled!=null)
if (mobileDataEnabled.equals(!toBeEnabled)){
Method m2 = null;
try {
int index=0;
boolean method_found=false;
Method[] available_methods= c.getDeclaredMethods();
for (Method method : available_methods) {
// following line doesn't work
// method.getName()=="setMobileDataEnabled"
if (method.getName().contains("setMobileDataEnabled"))
{
method_found=true;
}
if (method_found==false)
index++;
}
// following line doesn't work
//m2 = c.getDeclaredMethod("setMobileDataEnabled");
m2 = (c.getDeclaredMethods())[index];
if (m2!=null){
m2.setAccessible(true);
m2.invoke(cm,toBeEnabled);
}
} catch (SecurityException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (InvocationTargetException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
To make it working I also added the android.permission.WRITE_SECURE_SETTINGS" in the manifest and installed in /system/app according to Android: Add app to firmware, use WRITE_SECURE_SETTINGS.
Does anyone know a better way?
回答1:
try {
final ConnectivityManager cm = (ConnectivityManager) this.context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class connectivityManager = Class.forName(cm.getClass()
.getName());
final Method[] methods = connectivityManager.getDeclaredMethods();
for (final Method method : methods) {
if (MLauncherConnectivityManager.SET_MOBILE_DATA_ENABLED
.equals(method.getName())) {
method.invoke(cm, true);
}
}
} catch (final ClassNotFoundException e) {
Log.e("Class", e.getMessage());
} catch (final IllegalArgumentException e) {
Log.e("Class", e.getMessage());
} catch (final IllegalAccessException e) {
Log.e("Class", e.getMessage());
} catch (final InvocationTargetException e) {
Log.e("Class", e.getMessage());
}
来源:https://stackoverflow.com/questions/4955141/android-public-method-setmobiledataenabled-in-connectivitymanager-not-availabl