I am using below code to turn on/off mobile network.
final ConnectivityManager conman = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
final Class conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, ON);
I tested this code with Android 2.3.X, 4.0.X and 4.1.X. It is working with only 2.3.X and 4.0.X but failed with 4.1.X.
I am getting java.lang.NoSuchFieldException: mService exception while testing with Android Jelly Bean.
Is there any other solution to my problem? I added all required permissions in manifest file.
try
{
dataMtd = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class);
}
catch (SecurityException e1)
{
e1.printStackTrace();
}
catch (NoSuchMethodException e1)
{
e1.printStackTrace();
}
dataMtd.setAccessible(true);
try {
dataMtd.invoke(conm,true);
}
}
Where datamtd is a method.. Try with this my friend. I found it successful in my previous app. Hope this may help you. Sorry if not, since I'm not much experienced.:)
Related
In my application, I used a snippet code below
public static void setMobileDataEnabled(Context context, boolean enabled) {
try {
final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class<?> conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
final Class<?> iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
} catch (Exception e) {
e.printStackTrace();
}
Can anyone know when I used this code in my application, Google still allows me to upload my app, or will prevent/reject - because it is private API / forbidden API?
Yes, it is supported, and even recommended in the situation where you want compatibility with multiple versions of the Android OS in one apk file.
You can check the article from android official blog about reflection.
http://android-developers.blogspot.com.br/2009/04/backward-compatibility-for-android.html
I'm having android(OS_VERSION 4.0) device. I would like to share the files to another android device through the wifi networks. I know, This can be done through wifi p2p(WifiDirect) in android 4.0 above. But this is not possible in android 2.3.3 devices(Prior to Android 4.0). I found the Superbeam application does the file sharing through shared networks in android 2.3.3.This application create the wifi tethering without sharing the internet connection of the device. The created tethering is only used for sharing the files not for sharing the internet. How to achieve this concept. Can anyone help me?
This answer may help to someone having the same question. The simple logic i implemented is,
1.Create the wifi tethering(Hotspot)
2.Disable the mobile data connection
Code is,
//To enable the wifi hotspot
setWifiTetheringEnabled(true);
//To disable the mobile data cnnection
setMobileDataEnabled(false);
private void setWifiTetheringEnabled(boolean enable) {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
Method[] methods = wifiManager.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("setWifiApEnabled")) {
try {
method.invoke(wifiManager, null, enable);
} catch (Exception ex) {
}
break;
}
}
}
private void setMobileDataEnabled(Context context, boolean enabled) {
try {
final ConnectivityManager conman = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class conmanClass = Class
.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass
.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField
.get(conman);
final Class iConnectivityManagerClass = Class
.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass
.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
} catch (ClassNotFoundException | NoSuchFieldException
| IllegalAccessException | IllegalArgumentException
| NoSuchMethodException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I've been using the following code on android 2.3 - 4.4.4 without any errors. But on running it on android L developer preview it gives me the following error
10-15 15:51:53.499: D/phone(30419): java.lang.NoSuchMethodException: setMobileDataEnabled [boolean]
try {
// log.i("Application running on Ginger bread+");
final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class<?> conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
final Class<?> iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, ON);
} catch (Exception e) {
Log.d(TELEPHONY_SERVICE, e.toString());
}
Is there any work round for this problem.
Any help is appreciated
Sahil
setMobileDataEnabled has been removed in Android L.
Use this instead:
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
Method methodSet = Class.forName(tm.getClass().getName()).getDeclaredMethod( "setDataEnabled", Boolean.TYPE);
methodSet.invoke(tm,true);
Make sure you have this permission on your manifest:
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
This permission is for System apps only
I've always used this code to enable mobile data programmatically:
ConnectivityManager conman = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
#SuppressWarnings("rawtypes")
final Class conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
#SuppressWarnings("rawtypes")
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
#SuppressWarnings("unchecked")
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, true);
This worked well, except now on Android 4.4.2 where I get this exception:
java.lang.NoSuchMethodException: setMobileDataEnabled [boolean]
at java.lang.Class.getConstructorOrMethod(Class.java:472)
at java.lang.Class.getDeclaredMethod(Class.java:640)
at com.test.auto3gPro.ClasseConnessione.settaConnessione(ClasseConnessione.java:48)
at com.test.auto3gPro.receiver.ScreenBroadcastReceiver.onReceive(ScreenBroadcastReceiver.java:108)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:768)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5081)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Does anyone know how to fix this?
If you are using cyanogenmod the method setMobileDataEnabled(boolean) is changed in setMobileDataEnabled(String, boolean)...as you can see on this line of code.
So you can use the standard way and then in the NoSuchMethodException catch block try the "cyanogenmod" way like this:
Class[] cArg = new Class[2];
cArg[0] = String.class;
cArg[1] = Boolean.TYPE;
Method setMobileDataEnabledMethod;
setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", cArg);
Object[] pArg = new Object[2];
pArg[0] = getContext().getPackageName();
pArg[1] = true;
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, pArg);
I don't know if other mods are affected.
This worked for me on Android 4.4.4 release 2
public void onClick(View view){
ConnectivityManager dataManager;
dataManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
Method dataMtd = null;
try {
dataMtd = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dataMtd.setAccessible(true);
try {
dataMtd.invoke(dataManager, true);
} 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();
}
}
Reflection still works on the bleeding edge versions
Looks like you've discovered the danger of using reflection to play with internals of classes. I'm sure this wasn't exposed because enabling mobile data should be done by the user rather than by an application. If you really want to keep doing this, you'll have to look into the new source files of Android to find out the unexposed interfaces that you can discover at runtime and guard calls to this code by checks on the API level. I don't think I'd recommend programmatically changing mobile data though.
setMobileDataEnabled has been removed in Android L.
Use this instead:
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
Method methodSet = Class.forName(tm.getClass().getName()).getDeclaredMethod( "setDataEnabled", Boolean.TYPE);
methodSet.invoke(tm,true);
Make sure you have this permission on your manifest:
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
This permission is for System apps only
I'm trying to Enable / Disable Mobile Data Connexion.
I've used this code by rIHaN JiTHiN (Enable/Disable Mobile Data (GPRS) using code) and it's works perfectly on Android 4.0, but it's doesn't on my Galaxy S (Froyo 2.2)...
Is there a way to enable / disable data connexion programmatically ?
If anyone had any idea why it's doesn't work on Froyo, would be really helpful. According to rIHaN JiTHiN, this code works on all Android version...
You can check whether it is enabled or disabled by using below code
ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mMobile = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mMobile.isConnected()) {
//if internet connected
}
if it is disabled, you can enable it on your froyo device by using this one
void turnData(boolean ON) throws Exception
{
if(bv == Build.VERSION_CODES.FROYO)
{
Log.i("version:", "Found Froyo");
try{
Method dataConnSwitchmethod;
Class telephonyManagerClass;
Object ITelephonyStub;
Class ITelephonyClass;
TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
telephonyManagerClass = Class.forName(telephonyManager.getClass().getName());
Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony");
getITelephonyMethod.setAccessible(true);
ITelephonyStub = getITelephonyMethod.invoke(telephonyManager);
ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName());
if (ON) {
dataConnSwitchmethod = ITelephonyClass.getDeclaredMethod("enableDataConnectivity");
} else {
dataConnSwitchmethod = ITelephonyClass.getDeclaredMethod("disableDataConnectivity");
}
dataConnSwitchmethod.setAccessible(true);
dataConnSwitchmethod.invoke(ITelephonyStub);
}catch(Exception e){
Log.e("Error:",e.toString());
}
}
else
{
Log.i("version:", "Found Gingerbread+");
final ConnectivityManager conman = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
final Class conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, ON);
}
and also dont forget to add these to manifest
android.permission.UPDATE_DEVICE_STATS
android.permission.CHANGE_NETWORK_STATE
android.permission.ACCESS_NETWORK_STATE
android.permission.MODIFY_PHONE_STATE
android.permission.READ_PHONE_STATE