在 android 中启用或禁用移动数据时出现问题
problem happen while enabling or disabling the mobile data in android
我在 运行 此来源时发生异常:
public void setMobileDataState(boolean mobileDataEnabled) {
try {
TelephonyManager telephonyService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Method setMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("setDataEnabled", boolean.class);
if (null != setMobileDataEnabledMethod) {
setMobileDataEnabledMethod.invoke(telephonyService, mobileDataEnabled);
}
} catch (Exception ex) {
Log.e(TAG, "Error setting mobile data state", ex);
}
}
异常:
java.lang.reflect.InvocationTargetException
我正在我的应用程序中使用这段代码。它对我来说很好用。希望对你有帮助。
要检查数据是否已启用,您可以调用 getMobileDataState()
要将其设置为启用或禁用,您可以调用 setMobileDataState(boolean)
。传递 true 以启用移动数据,传递 false 以禁用移动数据
/*Changing mobile data state - True to turn it ON*/
public void setMobileDataState(boolean mobileDataEnabled) {
try {
final ConnectivityManager conman = (ConnectivityManager)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, mobileDataEnabled);
}
catch (Exception ex) {
Toasty.error(Main.this, "Exception: "+ex.getMessage(), Toast.LENGTH_SHORT).show();
}
}
/* getting mobile data current state - returns True if ON*/
public boolean getMobileDataState() {
try {
TelephonyManager telephonyService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Method getMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("getDataEnabled");
if (null != getMobileDataEnabledMethod) {
boolean mobileDataEnabled = (Boolean) getMobileDataEnabledMethod.invoke(telephonyService);
return mobileDataEnabled;
}
}
catch (Exception ex) {
Toasty.error(Main.this, "Exception: "+ex.getMessage(), Toast.LENGTH_SHORT).show();
}
return false;
}
在您想要打开移动数据
的地方调用它
setMobileDataState(true);
在你想关闭移动数据的地方调用这个
setMobileDataState(false);
更新:
您需要在 Manifest.xml
中添加 MODIFY_PHONE_STATE
权限
if (ActivityCompat.checkSelfPermission(context,
android.Manifest.permission.MODIFY_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.MODIFY_PHONE_STATE}, 101);
} else {
setMobileDataEnabled(true);
}
然后在onRequestPermissionsResult
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 101) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setMobileDataEnabled(true);
} else {
Toasty.error(this, "Permission required to perform this action..", Toast.LENGTH_SHORT).show();
showAlert();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
ShowAlertDialog
private void showAlert(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setCancelable(false);
dialog.setTitle("Permissions");
dialog.setMessage("Please allow this permission in Settings.");
dialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(Settings.this, Settings.class));
finish();
}
});
dialog.show();
}
您正在尝试使用反射获取和调用方法
Method setMobileDataEnabledMethod =
telephonyService.getClass().getDeclaredMethod("setDataEnabled",
boolean.class);
if (null != setMobileDataEnabledMethod) {
setMobileDataEnabledMethod.invoke(telephonyService, mobileDataEnabled);
}
java.lang.reflect.InvocationTargetException
是一个通用异常,如果您的代码在 运行 反射代码中有任何问题,则会抛出该异常。在这里,它可能意味着两件事:
- 您的程序无法找到您正在寻找的方法,这是很有可能的,因为
setDataEnabled
是在 api 26 中添加的(参考:android docs)
如果您的应用设备 运行 也 api < 26,则不应依赖此方法。
- 您没有调用此方法的权限。为此,您需要
MODIFY_PHONE_STATE
。
您可以调用 <invocationTargetExceptionObject>.getCause()
来获取这背后的真正异常。
我在 运行 此来源时发生异常:
public void setMobileDataState(boolean mobileDataEnabled) {
try {
TelephonyManager telephonyService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Method setMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("setDataEnabled", boolean.class);
if (null != setMobileDataEnabledMethod) {
setMobileDataEnabledMethod.invoke(telephonyService, mobileDataEnabled);
}
} catch (Exception ex) {
Log.e(TAG, "Error setting mobile data state", ex);
}
}
异常:
java.lang.reflect.InvocationTargetException
我正在我的应用程序中使用这段代码。它对我来说很好用。希望对你有帮助。
要检查数据是否已启用,您可以调用 getMobileDataState()
要将其设置为启用或禁用,您可以调用 setMobileDataState(boolean)
。传递 true 以启用移动数据,传递 false 以禁用移动数据
/*Changing mobile data state - True to turn it ON*/
public void setMobileDataState(boolean mobileDataEnabled) {
try {
final ConnectivityManager conman = (ConnectivityManager)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, mobileDataEnabled);
}
catch (Exception ex) {
Toasty.error(Main.this, "Exception: "+ex.getMessage(), Toast.LENGTH_SHORT).show();
}
}
/* getting mobile data current state - returns True if ON*/
public boolean getMobileDataState() {
try {
TelephonyManager telephonyService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Method getMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("getDataEnabled");
if (null != getMobileDataEnabledMethod) {
boolean mobileDataEnabled = (Boolean) getMobileDataEnabledMethod.invoke(telephonyService);
return mobileDataEnabled;
}
}
catch (Exception ex) {
Toasty.error(Main.this, "Exception: "+ex.getMessage(), Toast.LENGTH_SHORT).show();
}
return false;
}
在您想要打开移动数据
的地方调用它setMobileDataState(true);
在你想关闭移动数据的地方调用这个
setMobileDataState(false);
更新:
您需要在 Manifest.xml
中添加MODIFY_PHONE_STATE
权限
if (ActivityCompat.checkSelfPermission(context,
android.Manifest.permission.MODIFY_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.MODIFY_PHONE_STATE}, 101);
} else {
setMobileDataEnabled(true);
}
然后在onRequestPermissionsResult
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 101) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setMobileDataEnabled(true);
} else {
Toasty.error(this, "Permission required to perform this action..", Toast.LENGTH_SHORT).show();
showAlert();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
ShowAlertDialog
private void showAlert(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setCancelable(false);
dialog.setTitle("Permissions");
dialog.setMessage("Please allow this permission in Settings.");
dialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(Settings.this, Settings.class));
finish();
}
});
dialog.show();
}
您正在尝试使用反射获取和调用方法
Method setMobileDataEnabledMethod =
telephonyService.getClass().getDeclaredMethod("setDataEnabled",
boolean.class);
if (null != setMobileDataEnabledMethod) {
setMobileDataEnabledMethod.invoke(telephonyService, mobileDataEnabled);
}
java.lang.reflect.InvocationTargetException
是一个通用异常,如果您的代码在 运行 反射代码中有任何问题,则会抛出该异常。在这里,它可能意味着两件事:
- 您的程序无法找到您正在寻找的方法,这是很有可能的,因为
setDataEnabled
是在 api 26 中添加的(参考:android docs)
如果您的应用设备 运行 也 api < 26,则不应依赖此方法。
- 您没有调用此方法的权限。为此,您需要
MODIFY_PHONE_STATE
。
您可以调用 <invocationTargetExceptionObject>.getCause()
来获取这背后的真正异常。