How to capture ambient Networks in android - android

I am capturing the current network by using telephony service.
int networkType = mTelephonyManager.getNetworkType();
if(networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN){
Log.e("", "Connectivity telephone network exists");
String networkCode = mTelephonyManager.getNetworkOperator();
String networkName = mTelephonyManager.getNetworkOperatorName();
}
But after this I also want to capture the ambient or other available networks.
How can I achieve this ?
Adding more information about this.
In your android device, Settings-More-Wireless & networks- mobile Networks-Network Operators
This is under available network heading.
I want to know about this.
how can my app capture this information.

Related

Android wifimanager.startscan() in main thread or in background?

What philosophy of startscan is better to use when i wanna get list of available wifi network?
I'm do this in main thread:
List<ScanResult> wifiList;
wifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) wifiManager.setWifiEnabled(true);
wifiManager.startScan();
wifiList = wifiManager.getScanResults();
for (int i = 0; i < wifiList.size(); i++) {
String[] networkInfo = wifiList.get(i).toString().split(",");
if (networkInfo[0].trim().equals(AP_SEARCH_SSID))
petcub_networks++;
}
In all device which i'm use for test, it's work fine, except few samsung smartphone. It's happened on customer device and i can't debug it quickly.
Is some one have same problem with samsung? Or will be better scan AP in background? Can it solve my problem?
**UPD:**Essence of my problem in next: i'm wanna scan available wifi networks, then if needs network was found i'm make connect to it(to socket). This procedure used in pipeline like first step.
I'm sorry to inform you but the code snippets had lots of missing elements (in term of efficiency) and is also incorrect, Let me elaborate this in points:
startScan() only request a scan from the OS , it does not initiate a scan right away in some cases. so you need to check the return boolean from the call
Before calling startScan you should register a BroadcastReceiver for WifiManager.SCAN_RESULTS_AVAILABLE_ACTION and only in after that even you should get the results
You might not need to initiate a scan at a lot. a relatively fresh result may already be available. You can take a look on the timestamp value (API 17) of ScanResult to estimate how "fresh" the scan is
You don't check if the device has WIFI hardware at all
You only initiate a scan if the Wifi is on, Android devices (since API 16 I think) can scan for networks even if the WIFI is off
To check if you can initiate a scan use this (In a function the returns boolean):
if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
return false;
}
WifiManager mWifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
boolean ret = mWifiManager.isWifiEnabled();
ret = ret || ((android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) &&
mWifiManager.isScanAlwaysAvailable());
return ret;

Can I turn on WiFi-Direct from code? on API-16 (Android 4.2.2)

I am developing an application with NFC and wifi direct. I get the MAC address using NFC and the Wifi Direct to transfer data. I call discoverpeers() and could get success. But there is no callback WIFI_P2P_PEERS_CHANGED_ACTION, the callback comes only when I go to settings and the select wifidirect.
This was discussed in the other question
Can I turn on WiFi-Direct from code? on Android API-14 (ICS)
"I'd like to add that WiFi direct on JB and above (at least on AOSP) is not active all the time - it only appears to be. If you look at listeners for WiFi direct, it turns itself off after some time. It turns itself back on if you open the wifi direct menu, however. You might have to have the host do a peer search or initialize itself in order to be able to be found. Likely a battery saving trick. I have also found that it's blocking, since as it accepts a connection, the entire system will lock up and fail to connect sometimes. (The system invitation) – Mgamerz "
Can anyone suggest the solution for the problem WIFI_P2P_PEERS_CHANGED_ACTION callback is not got and can get only when manually go to settings->wifi->tap on wifidirect
I used two devices Samsung galaxy nexus and nexus 7 both running on 4.2.2
There is no available API to enable wifiP2P but you can invoke method "enableP2p" from android settings 4.0.1
WifiP2pManager manager = (WifiP2pManager) getActivity().getSystemService(Context.WIFI_P2P_SERVICE);
Channel channel = manager.initialize(getActivity(), getActivity().getMainLooper(), null);
try {
Method method1 = manager.getClass().getMethod("enableP2p", Channel.class);
method1.invoke(manager, channel);
//Toast.makeText(getActivity(), "method found",
// Toast.LENGTH_SHORT).show();
} catch (Exception e) {
//Toast.makeText(getActivity(), "method did not found",
// Toast.LENGTH_SHORT).show();
}
To disable wifiP2P use this method
Method method1 = manager.getClass().getMethod("disableP2p", Channel.class);
Not from code. The user has to. That's why the demo has the link to wifi settings in the action bar.
When you call manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
define onFailure and look at the reasonCode. If it's 0, then either the Wifi or WiFi direct is off.
If you look at the WiFi Direct demo app, the WifiDirectBroadcast Reciever, this piece of code looks at whether p2p is enabled specifically
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// UI update to indicate wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi Direct mode is enabled
activity.setIsWifiP2pEnabled(true);
} else {
activity.setIsWifiP2pEnabled(false);
activity.resetData();
}
Then when discover peers is called it looks at the variable set by setIsWifiP2pEnabled
thanks user3093354. to continue with your solution, in order to disable the p2p you have to invoke:
Method method1 = manager.getClass().getMethod("disableP2p", Channel.class);
//Try this it may be help you
WifiManager wifiManager = (WifiManager)this.getSystemService(this.WIFI_SERVICE);
wifiManager.setWifiEnabled(true); //True - to enable WIFI connectivity .
//False -disable WIFI connectivity.
//add this permissions in Manifest file :
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
You can load the wifi driver from a command prompt with the desired concurrency level if you are rooted:
/system/bin/insmod /system/lib/modules/wlan.ko con_mode=3
These are the values:
typedef enum
{
VOS_STA_MODE=0,
VOS_STA_SAP_MODE=1,
VOS_P2P_CLIENT_MODE,
VOS_P2P_GO_MODE,
VOS_MONITOR_MODE,
VOS_FTM_MODE = 5,
VOS_IBSS_MODE,
VOS_P2P_DEVICE_MODE,
VOS_MAX_NO_OF_MODE
} tVOS_CON_MODE;
This is for an Atheros card.

Effective way to detect current Audio Route in Android?

My application requires the ability to know the fundamental audio route the user has selected. On iOS this is trivial, as you just register for a callback and you know exactly where the audio is going.
On Android I was pleased to see the MediaRouter class, however to my dismay it turns out there is no predictable way to determine the route type. For example, when switching to a Bluetooth A2DP device, the only identifying item is the RouteInfo.getName() method, but this returns the friendly name of the A2DP device, so it is impossible to compare against.
I also have tried using the following broadcasts:
AudioManager.ACTION_AUDIO_BECOMING_NOISY
Intent.ACTION_HEADSET_PLUG
BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED
BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED
However this method is error prone. For example, if you are connected to Bluetooth A2DP, then you plug in headphones, it is easy to tell the route is "Headphones", but then when un-plugging the headphones you have to guess what route is still active, by recording the connected state from all Bluetooth events.
There are also difficulties in ascertaining the initial audio route when your application starts. HEADSET_PLUG is sticky, so that's good, but nothing else is...
Any suggestions on how to approach this and accurately detect this? And why is this such a difficult task in Android?
Here's a very hackish way of polling for the current route, which also supports detection of A2DP. Use at your own risk, as the interals of these classes could very well change in the future. It should work on Jellybean and Jellybean MR1, though.
String ouputDeviceName;
try {
MediaRouter mr = (MediaRouter)getSystemService(Context.MEDIA_ROUTER_SERVICE);
Class mediaRouterClass = Class.forName("android.media.MediaRouter");
Method getSystemAudioRouteMethod = mediaRouterClass.getMethod("getSystemAudioRoute");
RouteInfo ri = (RouteInfo)getSystemAudioRouteMethod.invoke(mr);
Class mediaRouterStaticClass = Class.forName("android.media.MediaRouter$Static");
Field staticField = mediaRouterClass.getDeclaredField("sStatic");
Field a2dpField = mediaRouterStaticClass.getDeclaredField("mBluetoothA2dpRoute");
AccessibleObject.setAccessible(new AccessibleObject[]{staticField}, true);
AccessibleObject.setAccessible(new AccessibleObject[]{a2dpField}, true);
Object a2dpRoute = a2dpField.get(staticField.get(null));
if (a2dpRoute != mr.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_AUDIO)) {
// Phone, Headphone, HDMI, etc..
ouputDeviceName = "name: " + ri.getName().toString();
} else {
// Audio is routed to A2DP
ouputDeviceName = "name: A2DP";
}
} catch (Exception e) {
e.printStackTrace();
}

Auto Toggle 2G/3G When Screen On/Off on Android

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!

Can you explain the Functionality of requestRouteToHost() in android?

In my code I am using requestRouteToHost() method:
Does this routing means changing the WIFI to 3G or vice versa??
My code is not working...
public static boolean isHostAvailable(Context context, String urlString) throws UnknownHostException, MalformedURLException {
boolean ret = false;
int networkType = ConnectivityManager.TYPE_WIFI;
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(cm != null){
NetworkInfo nf = cm.getActiveNetworkInfo();
if(nf != null){
networkType = nf.getType();
}
URL url = new URL(urlString);
InetAddress iAddress = InetAddress.getByName(url.getHost());
ret = cm.requestRouteToHost(networkType, ipToInt(iAddress.getHostAddress()));
}
return ret;
}
public static int ipToInt(String addr) {
String[] addrArray = addr.split("\\.");
int num = 0;
for (int i=0;i<addrArray.length;i++) {
int power = 3-i;
num += ((Integer.parseInt(addrArray[i])%256 * Math.pow(256,power)));
}
return num;
}
Thanks
I think this is an extremely poorly documented method, and while an above comment saying "consider it a ping" might be a reasonable interpretation, I don't think it's correct. The fact that it takes an int as a host address suggests it is a much lower-level method than that, and the comment in the JavaDoc This method requires the caller to hold the permission CHANGE_NETWORK_STATE is another clue, suggesting that this makes a change in the internal routing table of the device. This link provides a better explanation:
requestRouteToHost() doesn't establish connectivity on any network, it
only ensures that any traffic for the specified host will be routed
via the specified network type (wifi or mobile). Connectivity must
already exist on the specified network.
This explanation makes MUCH more sense, considering the permission required. It also appears that it will not work with WiFi. So, it appears what this method is useful for is the following: You wish to ensure that the connection made to a particular host will be made via a SPECIFIC interface and that interface is not WiFi. This might make sense for a long-term, low traffic, battery efficient connection, such as when you wish to keep a socket open to a server and wait for the server to send the occasional message. The mobile data interface would make more sense than WiFi, since you wouldn't need to keep the WiFi radio active the whole time, and the mobile network radio is always on anyway. Incidentally, this is EXACTLY how an iPhone's server "push" mechanism works: It keeps a socket to an Apple server constantly connected over the mobile data interface, waiting for the server to say something.
So, in opposition to the (currently chosen) correct answer, I suggest that the answer to the asker's question: Does this routing means changing the WIFI to 3G or vice versa?? is actually, "Yes, sort of!" If the method returns true, the caller is assured that connections to that IP address will happen over the indicated interface.
And to Google: Boo on you for not documenting some of your APIs better!
Method requestRouteToHost() does not change wifi to 3G or vice versa!
Official Documentation :
public boolean requestRouteToHost (int networkType, int hostAddress)
Ensure that a network route exists to deliver traffic to the specified host via the specified network interface. An attempt to add a route that already exists is ignored, but treated as successful.
Parameters
networkType the type of the network over which traffic to the specified host is to be routed
hostAddress the IP address of the host to which the route is desired
Returns
true on success, false on failure

Categories

Resources