i've making a file transfer app. i am using download manager in this. if backgroud data restriction is enabled, the transfers are being queued by the download manager.
i want to warn the user that file transfer doenst work if it is enabled.
is there a way to know if background data restriction is enabled programatically?
I want this to happen even in Android Marshmallow.
Thanks in advance.
The below code works for my phone of Android 10 .
#RequiresApi(api = Build.VERSION_CODES.N)
public boolean checkBackgroundDataRestricted() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Log.i("test","getRestrictBackgroundStatus ="+connMgr.getRestrictBackgroundStatus());
switch (connMgr.getRestrictBackgroundStatus()) {
case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED:
// Background data usage and push notifications are blocked for this app
return true;
case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED:
case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED:
// Data Saver is disabled or the app is whitelisted
return false;
}
return false;
}
Related
I have button that needs to get some data from a back-end server. The button is disabled while the device is not connected to WiFi/Mobile/Internet. The problem is that when pressing the WiFi button it takes some time till it actually connects (2-3 seconds). How to know when the devices is connecting so I can display a ProgressBar in that periode of time? Thanks
plenty of methods in THIS SO question. In short you should use BroadcastReceiver with IntentFilter with ConnectivityManager.CONNECTIVITY_ACTION action. Check out NetworkInfo.State DOC and pick appriopiate for reporting (create own listener with needed callbacks)
if you can afford only newer APIs then you can use NetworkCallback, in DOC you can see all methods, use appriopiate. But I doubt sadly due to Android fragmentation, still better way is mentioned first one.
Also remember that since Android N this broadcast won't fire when was declared in manifest, use Java examples and (un)register with Activity lifecycle
fun isInternetOncheck(context: Context): Boolean {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = cm.activeNetworkInfo
return networkInfo != null && networkInfo.isConnectedOrConnecting
}
if (!NetworkCaller.isInternetOncheck(context!!)) {
println("no internet connection")
} else {
fetchDataFromServer()
}
fetchDataFromServer(){
showProgressbar()
......
......
//code for fetching data
......
......
hideProgressbar()
}
I am developing an Android Application and I need to make sure that the user is connected to the internet somehow. I can already check for WiFi, however, not everyone will be near a WiFi zone all the time, so I am thinking that Mobile Data is a valid alternative (of course assuming that the device is capable of having a SIM and all). So far, I can check if the user has enabled his or her mobile data as follows:
if(checkForMobileNetworkActive()){
//with mobile active
}
else{ // mobile not active
}
What I want to do is this: If the mobile network is NOT active, I will ask the user to turn it on. Very similar to what I have done in the past where I prompt the user to turn on their Bluetooth or the Location services. However, upon searching online, most answers pointed me to opening the WiFi settings via intent as such:
Intent i = new Intent(Settings.ACTION_WIFI_SETTINGS);
startActivity(i);
I have 2 issues with this solution:
This opens a new activity and not an alert dialog-style prompt to turn the WiFi on.
This turns on the WiFi and not the Mobile Data.
Has anyone tried to prompt the user to turn on their Mobile Data? As much as possible, I want it to look like the dialog box prompt and not an entire new activity (which is bad user experience in my opinion). I've looked on how to do it programmatically, however, what I stumbled upon no longer works for non-rooted device on Android Lollipop+ and I don't want to run the risk of the app no longer running when users upgrade the OS of their Android Devices.
Edit
I saw the link posted in the comment below, and I've tried this:
if(checkForMobileNetworkActive()){
}
else{
Intent i = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
startActivity(i);
}
But it opens the Mobile Data/Data Roaming Settings as a new activity. While it works, it enables the user to check the checkbox for Mobile Data and pressing the back button goes back to my app, it is not a very smooth user experience.
First of all, you have to use this permission:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
After that, with this code, you can know whether it connected to internet by mobile data or not:
public static boolean isConnectedMobile(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
}
UPDATE 1:
If you want to enable/disable the mobile network in your app, you can use this solution:
private void enableMobileData(Context context, boolean enabled) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
final ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class conmanClass = Class.forName(cm.getClass().getName());
final Field connectivityManagerField = conmanClass.getDeclaredField("mService");
connectivityManagerField.setAccessible(true);
final Object connectivityManager = connectivityManagerField.get(cm);
final Class connectivityManagerClass = Class.forName(connectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = connectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(connectivityManager, enabled);
}
And don't forget to use this permission:
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
I've got a very simple app which lists the available WiFi access points (routers).
I have an AlertDialog set up whenever the app opens or resumes & WiFi isn't enabled. This takes a user to the WiFi settings where they turn on WiFi.
The user then hits the back button and returns to my app. My app then sees that WiFi is enabled and outputs a list.
The problem is, even though WiFi is enabled - the AP list isn't yet done (even though I'm checking if the scan has finished.
So, how can I pause my activity long enough so that I get a complete list?
WifiManager oWiFiManager = (WifiManager) getSystemService(WIFI_SERVICE);
// Only proceed if WiFi is Enabled
if (oWiFiManager.isWifiEnabled())
{
boolean bScanComplete = oWiFiManager.startScan();
if (bScanComplete)
{
/* Scan is complete. Safe to proceed.
* This is the problem area because for some reason there are no networks listed (but there are in reality).
*/
}
}
else
{
// Tell user WiFi is Disabled & take back to settings dialog
}
You should be able to use the ConnectivityManager to get the state of the Wifi adapter. From there you can check if it is connected or even available.
ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWifi.isConnected()) {
// Do whatever
}
Dont forget to add android.permission.ACCESS_NETWORK_STATE to your AndroidManifest.xml for this to work
How to detect programatically if traffic is going through VPN without using intent to connect to VPNService. Is there some system call?
This works :
private boolean checkVPN() {
ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getNetworkInfo(ConnectivityManager.TYPE_VPN).isConnectedOrConnecting();
}
It is possible to check it in Android API 21 an higher, but it seems doesn't work (on nexus 5 # 5.0.1, nexus 7 # 5.0.2). Why its not working?
Snippet of new API for check it (and all traffic is routed by vpn if connected):
#Inject
boolean checkVPN(ConnectivityManager connMgr) {
//don't know why always returns null:
NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_VPN);
boolean isVpnConn = networkInfo == null ? false : networkInfo.isConnected();
return isVpnConn;
}
The Android OS is aware of when a VPN connection is active (as it shows an icon in the status bar for the duration of a VPN connection) but there is no public API method (which would appear on the VpnService) to check for an active connection.
Two solutions occur. If you are dealing with a specific situation where you know the network topology, run 'ping' to see if a particular IP address is available - use System.exec. the ping command is present on Android devices with stock ROMs, I've used it as part of a solution to to provide a more granular view of the state of a data connection (ip address not allocated, ip address allocated but can't access the internet, can access the internet)
A better solution would be to run a traceroute instead and analyse the output. I've not checked if traceroute is present on Android devices with stock ROMs, I'll edit this answer later with more complete information.
You can detect VPN with following code in android. Code will work in new and older version of android. Below code is in Kotlin.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if(checkVPNStatus()) {
Log.d("VPN-RAJ", "is VPN Connected YES")
} else {
Log.d("VPN-RAJ", "is VPN Connected NO")
}
}
private fun checkVPNStatus(): Boolean {
val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(network)
Log.d("VPN-RAJ", "in New Android Version")
capabilities!= null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)
} else {
Log.d("VPN-RAJ", "in Old Android Version")
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_VPN)!!.isConnectedOrConnecting
}
}
}
I guess for most use-cases you want to check if the actively used network is using VPN instead of if just any network available is using VPN.
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_VPN)
... is returning a NetworkInfo for an available VPN Network. This might not be the active Network! Instead you could use the following snippet to test if the active Network is using VPN:
Network activeNetwork = connectivityManager.getActiveNetwork();
NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(activeNetwork);
boolean vpnInUse = caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
I want to write an android app. When screen off, this app should set for mobile data only 2G. When screen on, it should set for mobile data both(2G/3G).
To do so, I should change mobile data type programmatically. How can I do this ?
I checked network type and I got the correct result.
this rom does it but I want to know how to do this : http://www.gregsbits.com/2012/04/saving-your-battery-through-aokp-rom.html
onCreate()
TelephonyManager manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if(manager.getNetworkType()==TelephonyManager.NETWORK_TYPE_EDGE){
tx.setText("Edge");
int enabled = Settings.Secure.getInt(getContentResolver(),
"preferred_network_mode", -1);
Log.d("MYAPP", "2G only enabled: " + enabled);
}
else{
tx.setText("3G");
cm.setNetworkPreference(TelephonyManager.NETWORK_TYPE_EDGE); //I'm trying
cm.startUsingNetworkFeature(TelephonyManager.NETWORK_TYPE_EDGE, "Deneme"); //I'm trying
}
The third party access to the 2G/3G/LTE toggle setting is disabled by google starting from Android 5.0 Lollipop.
So without Rooting the device which runs the OS android 5.0 and above whatever the requirement you stated may not be possible to implement!