I am having an issue when try to connect to wireless network.
My code works ok I sucessfully connect to the network whit the problems described below.
I have a listview whit the wifi scan results.
When I click the first time my receiver is not getting the "completed" state.
After clicking the second time , and , without chosing any network it get connected and my code inside the "complete" is executed.
The code below is called from another class that thre reason why it is static
Coonect Code:
public static boolean connect(String ssid,String password)
{
String networkSSID = ssid;
String networkPass = password;
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + networkSSID + "\"";
conf.preSharedKey = "\""+ networkPass +"\"";
//WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
int netid=mainWifi.addNetwork(conf);
mainWifi.disconnect();
mainWifi.enableNetwork(netid, true);
//mainWifi.reconnect(); <-- exact the same issue discommenting this line
return true;
}
On the class were the connect is been called I have registered BradcastReceiver as follow:
public void onClick(View v)
{
mainWifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiinfo = mainWifi.getConnectionInfo();
AuthWifi authWifi = new AuthWifi();
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
getApplicationContext().registerReceiver(authWifi, mIntentFilter);
ClientManager.scan(CameraActivity.this, mainWifi);
}
my broadcast receiver
public class AuthWifi extends BroadcastReceiver {
#Override
public void onReceive(Context c, Intent intent) {
String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
SupplicantState supl_state = ((SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE));
switch (supl_state) {
case COMPLETED:
/////////////IF I AM CONNECTED THE WIFI SSID I CHOSE FROM A LISTVIEW THEN ---->
if(wifiinfo != null & wifiinfo.getSSID()!=null & ClientManager.getSSID() !=null& !conectado ) {
if (wifiinfo.getSSID().contains(ClientManager.getSSID().trim())) ///I know here is better .equals() /// I have contain for my own reasons
conectado = true;
/*HERE I DO SOME THINGS WHEN CONNECTED (I CALL A RUNNABLE TO MAKE A SERVER SOCKET)*/
}
}
break;
case DISCONNECTED:
Log.i("SupplicantState", "Disconnected");
conectado = false;
if (ClientStartReceive.isStopped)
{
ClientStartReceive.stop();
}
break;
default:
Log.i("SupplicantState", "Unknown");
break;
}
int supl_error = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
if (supl_error == WifiManager.ERROR_AUTHENTICATING) {
/////HERE I MANAGE AUTHENTICATION ERROR
}
}
}
}
Hope someone is able to help :( if you need more code to troubleshoot please let me know.
If you have some reference to help me even if i need to rebuild the code is accepted also.. My goal is be able to connect to a network ,show for authentication errors and execute some code on connection susscess.
Sorry for my english I think you have gessed I am not native.
Regards
As doc indicate that “COMPLETED“ use as follow:
This state indicates that the supplicant has completed its processing for the association phase and that data connection is fully configured. Note, however, that there may not be any IP address associated with the connection yet.
You should not rely this state to ensure your connection is completed. Instead, you can register an BroadcastReceiver listener for network status change.
Related
Recently i discovered that the implementation to connect to a Wifi in Android is deprecated for Android 10 or above and I'm trying to fix my application using WifiNetworkSpecifier. But I notice the WifiNetworkSpecifier do not save the network connection and just stay connected while the application is running and when it's closed, the wifi is disconnected and do not save the password.
I'm using this code:
private void connectByWifiNetworkSpecifier(String wifiSsid, String pass) {
Log.d(TAG, "connectByWifiNetworkSpecifier: wifi=" + wifiSsid + ", pass=" + pass);
connectivityManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
WifiNetworkSpecifier.Builder specifierBuilder = new WifiNetworkSpecifier.Builder()
.setSsid(wifiSsid)
.setWpa2Passphrase(pass);
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifierBuilder.build())
.build();
networkCallback = new ConnectivityManager.NetworkCallback() {
#Override
public void onAvailable(Network network) {
super.onAvailable(network);
Log.d(TAG, "onAvailable: network=" + network);
// do success processing here..
connectivityManager.bindProcessToNetwork(network);
}
#Override
public void onUnavailable() {
super.onUnavailable();
Log.d(TAG, "onUnavailable: ");
// do failure processing here..
}
};
connectivityManager.requestNetwork(request, networkCallback);
}
Have it any way to save the connection "permanently" (without me having to connect all the time and always put the password) using WifiNetworkSpecifier or another API?
.
So I need device A (client) to connect to device B (server) and I've gotten it to work, but not in all cases. Upon opening the app, I want to allow the device to be discovered
private void enableDiscoverability() {
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
3600);
startActivity(discoverableIntent);
}
, and i set up a receiver to look for one specific device (just for now, I'm still learning how to use Bluetooth)
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
TextView output = findViewById(R.id.output);
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice temp = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = temp.getName();
Log.i("Device ", deviceName + " was found");
String deviceHardwareAddress = temp.getAddress();
if (deviceHardwareAddress.equalsIgnoreCase("DC:F7:56:DD:73:8F")) {
device = temp;
startClient();
}
}
}
};
So here is my problem. When device A is left on, it'll discover new devices for a little while, but it won't discover the new device B after a few minutes. Both devices should have a receiver and should be discoverable.
Is there a timeout when you're discovering devices? Would something happen to the receiver if it tried to connect but failed? I've tried to look it up, but I'm still new with Bluetooth so I wouldn't know where to begin. I'd be more than happy to post more code if need be
Yes. Every device has a discovery timeout. Best place to start is bluetooth.com, with huge amount of videos and documents. There is timeout for every activity in Bluetooth such as discovery, connection, data transmission etc.
Here is what I am doing:
I register a BroadcastReceiver like this:
mConnectionChangeReceiver = new ConnectionChangeReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
mContext.registerReceiver(mConnectionChangeReceiver, filter, null, handler);
Then I automatically try connect to a specific WiFi. Something like this:
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}
mWifiManager.enableNetwork(mCurrentNetworkId, true);
I get the broadcast receiver events as expected. Inside onReceive() I check for the SSID and for SuplicantState. The problem is when I try to get the phone ip address. WifiInfo.getIpAddress returns 0 if the cellular network is enabled on the phone but it works if it is disabled.
Please note that this will work if the device was already connected to SSID in both cases (with/without cellular network). For this to happen wifi must de off or the phone must be connected to another wifi before running the code.
Here's the code:
public void onReceive(Context context, Intent intent) {
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
//..... Here's the code that compares SSID
if (isConnectedToSSID() && (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
mIpAddress = NetworkHelper.getIpAddress(wifiInfo);
}
}
public static String getIpAddress(WifiInfo pWifiInfo) {
int ipAddress = pWifiInfo.getIpAddress();
if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
ipAddress = Integer.reverseBytes(ipAddress);
}
byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray();
String ipAddressString = null;
try {
ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress();
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
return ipAddressString;
}
Any ideas why this happens?
I have read that the "ConnectivityManager" class gives information about the network. But I am confused on how to implement the code. I need an efficient way to check internet, wifi and GPRS at a time.
Thanks
And again: http://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION
You have to do something, nobody will write complete code for you. Read the documentation and you know when the event is fired and which you have to sort out.
Simply use this function. call this function where you want to check that internet is available or not.
public boolean isNetworkConnected(Context mContext) {
final String DEBUG_TAG = "NetworkStatusExample";
ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService(CONNECTIVITY_SERVICE);
boolean isWifiConn=false;
boolean isMobileConn=false;
Network nn=connMgr.getActiveNetwork();
Network[] networkinf=connMgr.getAllNetworks();
for (int a=0;a<networkinf.length;a++) {
NetworkCapabilities networkCapabilities = connMgr.getNetworkCapabilities(networkinf[a]);
if (networkCapabilities.hasTransport(networkCapabilities.TRANSPORT_CELLULAR)){
isMobileConn=true;
}
else if (networkCapabilities.hasTransport(networkCapabilities.TRANSPORT_WIFI)){
isWifiConn=true;
}
}
Log.i(DEBUG_TAG, "Wifi connected: " + isWifiConn);
Log.i(DEBUG_TAG, "Mobile connected: " + isMobileConn);
editor.putBoolean("isConnected",isMobileConn);
editor.apply();
if (isMobileConn || isWifiConn){
Log.i(DEBUG_TAG, "Network Status..." + isMobileConn);
return true;
}
else {
return false;
}
}
i have following function run on start and work perfectly.
i would like to add if condition in other function in order to check if device is still connected.
here is code
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BluetoothService.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BluetoothService.STATE_CONNECTED:
Toast.makeText(getApplicationContext(), "Connect successful",
Toast.LENGTH_SHORT).show();
btnClose.setEnabled(true);
btnSend.setEnabled(true);
btnSendDraw.setEnabled(true);
break;
case BluetoothService.STATE_CONNECTING:
Log.d("À¶ÑÀµ÷ÊÔ","ÕýÔÚÁ¬½Ó.....");
break;
case BluetoothService.STATE_LISTEN:
case BluetoothService.STATE_NONE:
Log.d("À¶ÑÀµ÷ÊÔ","µÈ´ýÁ¬½Ó.....");
break;
}
break;
case BluetoothService.MESSAGE_CONNECTION_LOST:
Toast.makeText(getApplicationContext(), "Device connection was lost",
Toast.LENGTH_SHORT).show();
btnClose.setEnabled(false);
btnSend.setEnabled(false);
btnSendDraw.setEnabled(false);
break;
case BluetoothService.MESSAGE_UNABLE_CONNECT:
Toast.makeText(getApplicationContext(), "Unable to connect device",
Toast.LENGTH_SHORT).show();
break;
}
}
};
other function is start like this
#Override
protected void onPostExecute(String result){
please help me!!
Thanks
ACL_CONNECTED/DISCONNECTED is not exactly reliable, I have learned by experience, because this might happen several times during a device's connection (example, if pin is required, you will get "connected", and then "disconnected" if timeout/wrong pin supplied. This does not necessarily indicate connection proper). This indicates the lower layer connection.
If you want to use a broadcast receiver, it would be better to use the broadcast that is specific to the profile that you have used (example A2DP). Each has it's own broadcast. Another thing you can listen to is Connectivity_state_changed from ConnectivityManager, for the type BLUETOOTH (haven't really tried this one).
Also, the way to check if it is connected, without a broadcast receiver, say, when you want to check in the background before updating an activity, would be to obtain the profile object, via something like:
mBluetoothAdapter.getProfileProxy(mContext, mA2DPProfileListener, BluetoothProfile.A2DP);
where mA2DPProfileListener is a ServiceListener object:
<code>
private ServiceListener mA2DPProfileListener = new ServiceListener(){
//anonymous inner type. etc.
public void onServiceConnected(int profile, BluetoothProfile proxy) {
//cast the BluetoothProfile object to the profile you need, say
//BluetoothA2DP proxyA2DP = (BluetoothA2DP) proxy;
int currentState = proxyA2DP.getConnectionState(mDevice);
//mDevice is the BluetoothDevice object you can get from
//BluetoothAdapter.getRemote...
}
public void onServiceDisconnected(int profile) {
}
}
</code>
you can check what currentState points to, and determine if the device is connected/disconnected/connecting, etc.
HTH,
Sreedevi.