How to check programmatically if data roaming is enabled/disabled? - android

I'm trying to check if the user has enabled/disabled data roaming. All I found so far is that you can check whether or not the user is currently IN roaming, using TelephonyManager.isNetworkRoaming() and NetworkInfo.isRoaming(), but they are not what I need.

Based on Nippey's answer, the actual piece of code that worked for me is:
public Boolean isDataRoamingEnabled(Context context) {
try {
// return true or false if data roaming is enabled or not
return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.DATA_ROAMING) == 1;
}
catch (SettingNotFoundException e) {
// return null if no such settings exist (device with no radio data ?)
return null;
}
}

You can request the state of the Roaming-Switch via
ContentResolver cr = ContentResolver(getCurrentContext());
Settings.Secure.getInt(cr, Settings.Secure.DATA_ROAMING);
See: http://developer.android.com/reference/android/provider/Settings.Secure.html#DATA_ROAMING

public static final Boolean isDataRoamingEnabled(final Context application_context)
{
try
{
if (VERSION.SDK_INT < 17)
{
return (Settings.System.getInt(application_context.getContentResolver(), Settings.Secure.DATA_ROAMING, 0) == 1);
}
return (Settings.Global.getInt(application_context.getContentResolver(), Settings.Global.DATA_ROAMING, 0) == 1);
}
catch (Exception exception)
{
return false;
}
}

Updated function to account for API deprecation. It is now replaced with:
http://developer.android.com/reference/android/provider/Settings.Global.html#DATA_ROAMING
public static boolean IsDataRoamingEnabled(Context context) {
try {
// return true or false if data roaming is enabled or not
return Settings.Global.getInt(context.getContentResolver(), Settings.Global.DATA_ROAMING) == 1;
}
catch (SettingNotFoundException e) {
return false;
}
}

Related

Android app to dynamically turn on/off a wifi hotspot

I want to control wifi hotspot dynamically in my Android app project. I have tired Reflection (which will not work in Android Oreo and later versions), startLocalOnyNetwork (but I want specific SSID and PASSWORD, which is not possible to configure it).
Then I rooted my phone, Is it possible if the device is rooted ?
Expecting an api to turn on/off wifi hotspot with specific SSID and PASSWORD or use the previous one.
Any possibilities or workarounds ?
Thanks in advance.
To turn on Wifi Hotspot, need some permissions
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
and the permission should be dynamically granted by user
In apps advanced settings -> Modify system settings
/**
* This enables tethering using the ssid/password defined in Settings App>Hotspot & tethering
* Does not require app to have system/privileged access
* Credit: Vishal Sharma - https://stackoverflow.com/a/52219887
*/
public boolean startTethering() {
File outputDir = mContext.getCodeCacheDir();
Object proxy;
try {
proxy = ProxyBuilder.forClass(OnStartTetheringCallbackClass())
.dexCache(outputDir).handler(new InvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
}).build();
} catch (Exception e) {
Log.e(TAG, "Error in enableTethering ProxyBuilder");
e.printStackTrace();
return false;
}
Method method = null;
try {
method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
if (method == null) {
Log.e(TAG, "startTetheringMethod is null");
} else {
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
Log.d(TAG, "startTethering invoked");
}
return true;
} catch (Exception e) {
Log.e(TAG, "Error in enableTethering");
e.printStackTrace();
}
return false;
}
public void stopTethering() {
try {
Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
if (method == null) {
Log.e(TAG, "stopTetheringMethod is null");
} else {
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
Log.d(TAG, "stopTethering invoked");
}
} catch (Exception e) {
Log.e(TAG, "stopTethering error: " + e.toString());
e.printStackTrace();
}
}
Use above methods to turn on/off Wifi Hotspot with SSID and password defined in the settings.
private int AP_STATE_DISABLED = 11;
private int AP_STATE_ENABLING = 12;
private int AP_STATE_ENABLED = 13;
private int AP_STATE_ERROR = 14;
/**
* #return status hot spot enabled or not
*/
public boolean isHotSpotEnabled(Context context) {
Method method = null;
int actualState = 0;
try {
WifiManager mWifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
method = mWifiManager.getClass().getDeclaredMethod("getWifiApState");
method.setAccessible(true);
actualState = (Integer) method.invoke(mWifiManager, (Object[]) null);
if (actualState == AP_STATE_ENABLING ||actualState == AP_STATE_ENABLED) {
return true;
}
} catch (IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
Above method can be used to get the current state of hotspot

PackageManager check of isEphemeralDisabled causes a deadlock on Android 7.1

private boolean isEphemeralAllowed(
Intent intent, List<ResolveInfo> resolvedActivities, int userId,
boolean skipPackageCheck) {
// Short circuit and return early if possible.
if (isEphemeralDisabled()) {
return false;
}
final int callingUser = UserHandle.getCallingUserId();
if (callingUser != UserHandle.USER_SYSTEM) {
return false;
}
if (mEphemeralResolverConnection == null) {
return false;
}
if (intent.getComponent() != null) {
return false;
}
if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
return false;
}
if (!skipPackageCheck && intent.getPackage() != null) {
return false;
}
final boolean isWebUri = hasWebURI(intent);
private boolean isEphemeralDisabled() {
// ephemeral apps have been disabled across the board
if (DISABLE_EPHEMERAL_APPS) {
return true;
}
// system isn't up yet; can't read settings, so, assume no ephemeral apps
if (!mSystemReady) {
return true;
}
// we can't get a content resolver until the system is ready; these checks must happen last
final ContentResolver resolver = mContext.getContentResolver();
if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) {
return true;
}
return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0;
}
For Android 7.0, DISABLE_EPHEMERAL_APPS default is true
private static final boolean DISABLE_EPHEMERAL_APPS = true;
But in Android 7.1, Google enabled Instant apps support: https://android.googlesource.com/platform/frameworks/base.git/+/7ef97b6624054fff0d712d85336a45eee70bcc3f%5E%21/#F0
for isEphemeralAllowed method, if call resolveIntent, most of intents will call isEphemeralAllowed method, so this will cause PackageManager service user binder call settingProvider, and will probability cause a deadlock.

Check if screen is in MultiWindowMode without activity

Is there any way to find out if screen is split if I have no access to Activity? (Structurally I can't call isInMultiWindowMode method.
I see that default Activity#isInMultiWindowMode() implementation is:
public boolean isInMultiWindowMode() {
try {
return ActivityManagerNative.getDefault().isInMultiWindowMode(mToken);
} catch (RemoteException e) {
}
return false;
}
Is there any workaround ?
I think the only way to do this without an Activity is by using an AccessibilityService that has the permissions to get the list of windows currently displayed and check if there's a window whose type is AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER.
For example, you could have the following method to do so:
private boolean inSplitScreenMode(List<AccessibilityWindowInfo> windows) {
for (AccessibilityWindowInfo window : windows) {
if (window.getType() == AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER) {
return true;
}
}
return false;
}
check this method when receiving window state changed accessibility events
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if ((event.getEventType() & AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) != 0) {
if (inSplitScreenMode(getWindows()) {
Log.d(TAG, "Split screen mode detected");
} else {
Log.d(TAG, "No split screen");
}
}
}
Inside Fragment you can use
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (((Activity)getContext()).isInMultiWindowMode()){
// ...
}
}

Detect if 'High contrast' is enabled in Android accessibility settings

How can I detect if 'High Contrast' setting (available on Android 5.0+) is enabled in Accessibility settings?
In the AccessibilityManager class (see source here) you have a public method called isHighTextContrastEnabled that you can use to get your information:
/**
* Returns if the high text contrast in the system is enabled.
* <p>
* <strong>Note:</strong> You need to query this only if you application is
* doing its own rendering and does not rely on the platform rendering pipeline.
* </p>
*
* #return True if high text contrast is enabled, false otherwise.
*
* #hide
*/
public boolean isHighTextContrastEnabled() {
synchronized (mLock) {
IAccessibilityManager service = getServiceLocked();
if (service == null) {
return false;
}
return mIsHighTextContrastEnabled;
}
}
So in your code, you can access this method by doing so (if you're in an Activity):
AccessibilityManager am = (AccessibilityManager) this.getSystemService(Context.ACCESSIBILITY_SERVICE);
boolean isHighTextContrastEnabled = am.isHighTextContrastEnabled();
#alxscms' answer may be right but it does not help me So I found an alternative way to check High contrast text is Enabled or not in android.
Below function will return true if HighContrastText is enabled in user phone and otherwise return false.
Below function is checked in all android phones and it's working.
public static boolean isHighContrastTextEnabled(Context context) {
if (context != null) {
AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
Method m = null;
if (am != null) {
try {
m = am.getClass().getMethod("isHighTextContrastEnabled", null);
} catch (NoSuchMethodException e) {
Log.i("FAIL", "isHighTextContrastEnabled not found in AccessibilityManager");
}
}
Object result;
if (m != null) {
try {
result = m.invoke(am, null);
if (result instanceof Boolean) {
return (Boolean) result;
}
} catch (Exception e) {
Log.i("fail", "isHighTextContrastEnabled invoked with an exception" + e.getMessage());
}
}
}
return false;
}
I hope this can help many more others.
we can check highContrast fonts like this
public boolean isHighTextContrastEnabled(Context context) {
return Settings.Secure.getInt(context.getContentResolver(), "high_text_contrast_enabled", 0) == 1;
}

how to find a rooted device?

I was been trying to find whether a device is rooted or not and if the device is found rooted i do not want my application to get installed.I have tried two of the below methods
private boolean isRooted() {
return findBinary("su");
}
public static boolean findBinary(String binaryName) {
boolean found = false;
if (!found) {
String[] places = { "/sbin/", "/system/bin/", "/system/xbin/",
"/data/local/xbin/", "/data/local/bin/",
"/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/" };
for (String where : places) {
if (new File(where + binaryName).exists()) {
found = true;
break;
}
}
try {
File file = new File("/system/app/Superuser.apk");
if (file.exists()) {
Log.e("ERROR", "Unable to find icon for package '"
+ "apk found");
found = true;
}
} catch (Exception e1) {
// ignore
}
}
return found;
}
But i don't think that these methods are enough to find a rooted device,since there are tools to hide an apk and the su file can be renamed or deleted.Is there any other way or any suggestions which is 100 percent reliable to find a rooted device?
I was trying to edit the su but couldn't do anything.Is it just a word of mouth or really possible to do so? Thanks in advance
***EDITED***:
I have used "HIDE MY ROOT" application to hide the SU binary aswell as superuser.apk.I can make my rooted device, look like unrooted using hide my root application.Therefore i can say that this source is falseproof and not completely reliable to find rooted device.
Kindly let me know if there is any alternative way to find the rooted device..
I did this in the following way :
/*
* Run su command on device
* #throws IOException, InterruptedException
*/
private static boolean suRun() throws IOException, InterruptedException
{
try {
Process su = null;
su = Runtime.getRuntime().exec(new String[] {"su","-c","exit"});
su.waitFor();
InputStream in = su.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
String suOutput = bufferedReader.readLine();
if (suOutput == null)
{
return true;
}
else
{
return false;
}
} catch (Exception ex)
{
return false;
}
}
public static boolean isPhoneRooted() {
// check if /system/app/Superuser.apk is present and can run su
try {
File file = new File("/system/app/Superuser.apk");
if (file.exists() && suRun()) {
Log.d("Blocking Service", "ROOTED PHONE DETECTED");
return true;
}
}
catch (Throwable e1) {
// ignore
}
return false;
}
you can use SafetyNet API from google play service. this is what being used by android pay not only for the root detection but also to check compatibility with android CTS.
Call isRooted() from ShellInterface
isRooted() depend upon majority of three factor
public static boolean isRooted() {
return isRooted1() ? (isRooted2() || isRooted3()) : (isRooted2() && isRooted3());
}
private static boolean isRooted1() {
Process mProcess = null;
boolean mRoot;
try {
// This is executing on terminal
mProcess = Runtime.getRuntime().exec("su");
mRoot = true;
// If the execute successfully then it return to true
} catch (Exception e) {
// if is not successfully then it return to false
mRoot = false;
} finally {
if (mProcess != null) {
try {
mProcess.destroy();
} catch (Exception ignored) {
}
}
}
return mRoot;
}
private static boolean isRooted2() {
String buildTags = Build.TAGS;
return buildTags !=null && buildTags.contains("test-keys");
}
private static boolean isRooted3() {
boolean mRoot = false;
boolean found = false;
if (!found) {
String[] places = {"/sbin/", "/system/bin/","/system/xbin",
"/data/local/xbin","/system/sd/xbin","/data/local"
};
for (String path : places){
if (new File(path+"su").exists()) {
mRoot = true;
found = true;
}
}
}
return mRoot;
}

Categories

Resources