Unable to get data roaming status on Moto Devices Android? - android

I need to get access to the Data Roaming Status on Moto Device(5.0.1)
if (Settings.Secure.getInt(context.getContentResolver(),Settings.Secure.DATA_ROAMING) == 1) {
//Data Roaming Enabled
flag = true;
} else {
// Data Roaming Disabled
flag = false;
}
I found problem with this when using a Motorola device. Secure Settings in this device are found in android.provider.MotorolaSettings.Secure where as in other devices it's android.provider.Settings.Secure.
Is there a way to resolve this or any other way to get roaming status?

One solution here, use reflection to check if Motorola classes are availables.
If they're not here, you need to use the default api, then call getInt on the available system.
Not able to test it on a Motorola device.
public static boolean isEnabled(Context context){
Class<?> baseSettingsClass = null;
// Retrieve the 'default' settings api
try {
if (android.os.Build.VERSION.SDK_INT >= 17){
baseSettingsClass = Class.forName( "android.provider.Settings$Global");
}
else{
baseSettingsClass = Class.forName( "android.provider.Settings$Secure" );
}
}catch(Exception e){}
Class<?> secureClass = null;
// Try retrieve the motorola class
try{
secureClass = Class.forName("com.motorola.android.provider.MotorolaSettings$Secure" );
}catch(Exception e){}
// If it failed, use the 'default' api class
if (secureClass == null){
if (baseSettingsClass != null){
secureClass = baseSettingsClass;
}
else{
return false;
}
}
try {
// Retrieve the getInt method
Method getIntMethod = secureClass.getDeclaredMethod("getInt", ContentResolver.class, String.class);
// Execute getInt(context.getContentResolver(), Settings.Secure.DATA_ROAMING)
int result = (Integer) (getIntMethod.invoke(null, context.getContentResolver(), (String)baseSettingsClass.getField("DATA_ROAMING").get(null)));
return result == 1;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}

Related

Check For Internet Connectivity Causes Android Not Responding Error

This is my first app, so I'm still learning. I created a class (Check Network) that I call on to check for internet connectivity before I display an ad. The method in the class returns a boolean, here is the first method - a test connection to Google:
public boolean isConnectedToGoogle() {
Runtime runtime = Runtime.getRuntime();
boolean reachGoogle = false;
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
if(exitValue == 0) {
reachGoogle = true;
} else {
reachGoogle = false;
}
} catch (IOException e) {
//e.printStackTrace();
reachGoogle = false;
} catch (InterruptedException e) {
//e.printStackTrace();
reachGoogle = false;
}
return reachGoogle;
}
Next, I use the above method in the method below to test the network, and return true or false:
public boolean isNetworkNull(Context context) {
boolean isNetWorkNull;
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if(activeNetwork != null) {
if(isConnectedToGoogle()) {
isNetWorkNull = false;
} else {
isNetWorkNull = true;
}
} else {
isNetWorkNull = true;
}
return isNetWorkNull;
}
So, throughout my app I use the code to test the connection:
boolean isNetworkNull = checkNetwork.isNetworkNull(getApplicationContext());
if(isNetworkNull) {
// do this
} else {
// do that
}
In my Google Play Console I've discovered numerous "Android Not Responding" events due to the isConnectedToGoogle() method. The console states:
nameOfApp.CheckNetwork.isConnectedToGoogle
input dispatching time out
The best I can understand is the call to Google is taking too long (maybe the phone has a weak internet connection) and thus it times out and the app records an android not responding error.
If this is accurate, is there a way to say "listen" and if no response received from Google after time X have the isConnectedToGoogle skip the check and just return a true or false? Or is there a better approach to this? Any assistance would be greatly appreciated.
I think I found the answer after doing a bit more research. I changed the code as such for the isConnectedToGoogle() Method:
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
// int exitValue = ipProcess.waitFor(); // original
boolean wasGoogleReached = ipProcess.waitFor(1000, TimeUnit.MILLISECONDS);
if(wasGoogleReached) {
reachGoogle = true;
} else {
reachGoogle = false;
}
I believe this should handle the time out. This link also helped.

How to get my device bluetooth id.i try to get but they all time return 02:00:00:00:00:00

Hello I try to get my Bluetooth device id but that's not working.
i try below code so can you check which mistake is i made in that.
public static String getBluetoothMacAddress(Context context) {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String bluetoothMacAddress = "0";
try {
Field mServiceField = bluetoothAdapter.getClass().getDeclaredField("mService");
mServiceField.setAccessible(true);
Object btManagerService = mServiceField.get(bluetoothAdapter);
if (btManagerService != null) {
bluetoothMacAddress = (String) btManagerService.getClass()
.getMethod("getAddress").invoke(btManagerService);
Utils.printLog("bluetoothMacAddress ", bluetoothMacAddress);
}
bluetoothMacAddress= android.provider.Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");
} catch (Exception e) {
Utils.printLog("bluetoothMacAddress1 ", e.getMessage());
}
if (bluetoothMacAddress == null || bluetoothMacAddress.equals("") || bluetoothMacAddress.equals("02:00:00:00:00:00")) {
bluetoothMacAddress = "0";
}
Utils.printLog("bluetoothMacAddress ", bluetoothMacAddress);
return bluetoothMacAddress;
}
You mac address is a sort of id actually but on network layer, so that network can identify your device. You should always get same mac address for particular device, though there are some exceptions in manufacturing when multiple device could have same mac (like Arduino controllers). However, this is EXCEPTIONAL, rather than general

How to know which SIM is consuming mobile data in dual SIM android phone?

I am building a network monitor app. Here I have successfully implemented all the things like track data usage from Wifi or mobile data, but I want to know which SIM is connected to internet and consuming mobile data.
Using below code I am able to know if my dual sim phone is connected to Wifi or mobile data.
public static String isInternetConnected (Context ctx) {
ConnectivityManager connectivityMgr = (ConnectivityManager) ctx
.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo wifi = connectivityMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo mobile = connectivityMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
// Check if wifi or mobile network is available or not. If any of them is
// available or connected then it will return true, otherwise false;
if (wifi != null) {
if (wifi.isConnected()) {
return "wifi";
}
}
if (mobile != null) {
if (mobile.isConnected()) {
return "mobile";
}
}
return "none";
}
How can I get SIM Index or sim operator name that is consuming mobile data in dual sim android phone?
I had searched a lot and I saw many question posted in SO without answer like this.
I am able to get subId of both SIM in dual SIM phone but I am phasing problem to know which SIM is using internet.
Many other application are able to do this like Mubble.
Can any one provide me a solution for it?
After api level 22, you can use the hidden
system api android.telephony.SubscriptionManager#getDefaultDataSubId via reflection to get current active data sim subscription index.
After api level 24, there is a public system api android.telephony.SubscriptionManager#getDefaultDataSubscriptionId to get current active data sim subscription index.
Then, you can create a android.telephony.TelephonyManager or android.telephony.SubscriptionManager#getActiveSubscriptionInfo from subscription index to obtain sim operator information.
Here is a simple solution to get data sim operator for dual sim phone.
public static String getDataSimOperator(Context context) {
if (context == null) {
return null;
}
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (tm != null) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
int dataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
TelephonyManager dataSimManager = tm.createForSubscriptionId(dataSubId);
return dataSimManager.getSimOperator();
} else {
String operator = getDataSimOperatorBeforeN(context);
if (operator != null) {
return operator;
} else {
return tm.getSimOperator();
}
}
} else {
return tm.getSimOperator();
}
}
return null;
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
private static String getDataSimOperatorBeforeN(Context context) {
if (context == null) {
return null;
}
int dataSubId = -1;
try {
Method getDefaultDataSubId = SubscriptionManager.class.getDeclaredMethod("getDefaultDataSubId");
if (getDefaultDataSubId != null) {
getDefaultDataSubId.setAccessible(true);
dataSubId = (int) getDefaultDataSubId.invoke(null);
}
} catch (Exception e) {
e.printStackTrace();
}
if (dataSubId != -1) {
SubscriptionManager sm = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
if (sm != null && ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
== PackageManager.PERMISSION_GRANTED) {
SubscriptionInfo si = sm.getActiveSubscriptionInfo(dataSubId);
if (si != null) {
// format keep the same with android.telephony.TelephonyManager#getSimOperator
// MCC + MNC format
return String.valueOf(si.getMcc()) + si.getMnc();
}
}
}
return null;
}

When does getSimSerialNumber return a null value?

So here's the scenario.
When I had first tested my application which uses
getSimSerialNumber() function, I successfully got my SIM Number to be "89912000107679766XYZ".
Now, everytime I run the same function, irrespective of Airplane Mode being on or off, I keep getting Null Value.
I tried to check using getSimState(), and I always get the Constant value 5, which is "SIM_STATE_READY".
Where exactly is the issue? Why wouldn't I get the correct SimSerialNumber now?
EDIT 1:
Code base for reference:
public void doSimStateCheck(Context c){
String savedSimCardNo = ClientConfig.readSimCardNumber(c); // I have saved device's sim card somewhere here.
String existingSimCardNo = "";
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String simID = "";
boolean airPlaneMode = isAirplaneModeOn(c);
if(airPlaneMode){
// toggle airplane mode
setAirplaneModeOn(c,0); //Setting Airplane mode on - this might not work as stated for Jellybean and above. I have given WRITE_SETTINGS and WRITE_SECURE_SETTINGS permission already. I am not worried about this piece of code anyways.
simID = tm.getSimSerialNumber();
setAirplaneModeOn(c, 1); //Setting Airplane mode back to off.
}
else{
simID = tm.getSimSerialNumber(); // I am getting null here, i.e. when Airplane mode is NOT on, still I get null :( THIS IS MY CONCERN.
}
if (simID != null)
existingSimCardNo = simID;
else{
Log.v("SimState",""+tm.getSimState()); // This always returns 5.
existingSimCardNo = "NULL";
}
Log.v("SavedSimCardState", "It is " + savedSimCardNo); //This returns 89912000107679766XYZ
Log.v("ExistingSimCardState","It is "+existingSimCardNo); //This shows NULL as stated above.
if(!savedSimCardNo.equals(existingSimCardNo)){
//do stuff when sim card numbers are not same as saved earlier.
}
}
#SuppressWarnings("deprecation")
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static boolean isAirplaneModeOn(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) != 0;
} else {
return Settings.Global.getInt(context.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
}
}
#SuppressWarnings("deprecation")
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static void setAirplaneModeOn(Context context,int state) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
Settings.System.putInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, state);
} else {
Settings.Global.putInt(context.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, state);
}
}

How to find out whether android device has cellular radio module?

How can I find out for sure that device really has gsm, cdma or other cellular network equipment (not just WiFi)?
I don't want to check current connected network state, because device can be offline in the moment.
And I don't want to check device id via ((TelephonyManager) act.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId() because some devices would just give you polymorphic or dummy device ID.
Actualy, I need to check cell equipment exactly for skipping TelephonyManager.getDeviceId and performing Settings.Secure.ANDROID_ID check on those devices that don't have cellular radio. I have at least one tablet (Storage Options Scroll Excel 7") which returns different IMEIs every time you ask it, although it should return null as it has no cell radio (the same situation here: Android: getDeviceId() returns an IMEI, adb shell dumpsys iphonesubinfo returns Device ID=NULL). But I need to have reliable device id that is the same every time I ask.
I'd be glad to hear your thoughts!
If you're publishing in the store, and you want to limit your application only being visible to actual phones, you could add a <uses-feature> into your manifest that asks for android.hardware.telephony. Check out if that works for you from the documentation.
Just in case somebody needs complete solution for this:
Reflection is used because some things may not exist on some firmware versions.
MainContext - main activity context.
static public int getSDKVersion()
{
Class<?> build_versionClass = null;
try
{
build_versionClass = android.os.Build.VERSION.class;
}
catch (Exception e)
{
}
int retval = -1;
try
{
retval = (Integer) build_versionClass.getField("SDK_INT").get(build_versionClass);
}
catch (Exception e)
{
}
if (retval == -1)
retval = 3; //default 1.5
return retval;
}
static public boolean hasTelephony()
{
TelephonyManager tm = (TelephonyManager) Hub.MainContext.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null)
return false;
//devices below are phones only
if (Utils.getSDKVersion() < 5)
return true;
PackageManager pm = MainContext.getPackageManager();
if (pm == null)
return false;
boolean retval = false;
try
{
Class<?> [] parameters = new Class[1];
parameters[0] = String.class;
Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
Object [] parm = new Object[1];
parm[0] = "android.hardware.telephony";
Object retValue = method.invoke(pm, parm);
if (retValue instanceof Boolean)
retval = ((Boolean) retValue).booleanValue();
else
retval = false;
}
catch (Exception e)
{
retval = false;
}
return retval;
}

Categories

Resources