I have an application which needs to communicate with the server at some random interval through GPRS or EDGE.. But there are few possibilities at which internet cannot be accessed by the application when the user is in call or deactivated etc. At these time i have two scenario's recoverable and non recoverable.
Recoverable scenarios
On phone call ( User will hang up and data connection will be active
again)
No Signal (Sometimes signal may drop and the phone will get
signal again)
Non Recoverable Scenarios
Flight mode
Deactivating Data Connection
When its recoverable i can try again for the connection after some defined interval. And during non recoverable i have to alert user. For instance if the user deactivates data connection or enables flight mode i have to alert the user.
EDIT:I can able to detect flight mode through one of the intents. I couldn't able to find for others.
The below code return if valid connections are available
public boolean isConnectionsAvailable() {
boolean lRet = false;
try{
ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info= conMgr.getActiveNetworkInfo();
if(info != null && info.isConnected()) {
lRet = true ;
}else{
lRet = false ;
}
}catch (Exception e) {
Log.d("Connection Error", e.toString());
lRet = false ;
}
return lRet;
}
After this, if you have low signal strength then you make a HTTP request by setting relevant time out to it. If timeout happened give relevant alert msg to user as below
public void serverCall(String pURL){
if (isConnectionsAvailable()){
// Call server by setting proper timeout
}
}
Edit:
To check the Airplane mode status:
private static boolean isAirplaneModeOn(Context context) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) != 0;
}
You could try surrounding your method with try and catch. If the method fails because it cannot connect to your server for whatever reason you could call postDelayed from a Handler and re-run your method again in a pre-determined length of time.
Handler mHandler = new Handler();
Runnable yourMethodRunnable = new Runnable(){
#Override
public void run(){
yourMethod();
}
};
private void yourMethod(){
try{
// talk to server
} catch (InCallException e) {
mHandler.postDelayed(yourMethodRunnable, delay)
} catch (NoSignalException e) {
// etc...
} catch (OtherException e) {
// etc...
}
}
The exceptions are just examples, and likely don't exist, get the exceptions that you want to catch either from the Android Developer Docs, or by looking at the output from LogCat when you re-enact each time that the connection to the server would fail.
Related
I've seen many other posts regarding this specific issue, all with results that did not help me or were relevant to my case.
Here is my problem, I'm trying to setup a bluetooth piconet, with one node as a server and 7 as clients, each given a number as a location representative starting from 0 ( the server) and going to 7 (the clients). Currently I'm trying to get this to work for just two devices, the server and one client. And I assume that they're already paired. In the following code uuid is
private UUID uuid=UUID.fromString("0000111f-0000-1000-8000-00805f9b34fb");
Here is my thread which accepts incoming connections, ad is just the bluetooth adapter
private class BTServerThread implements Runnable{
#Override
public void run() {
try {
if (ad != null) {
if (ad.isEnabled()) {
BluetoothServerSocket btss=ad.listenUsingInsecureRfcommWithServiceRecord("MyApp",uuid);
Location=0;
Integer loc=1;
Log.wtf("Server","Searching");
while(loc<=7){
Thread t=new Thread(new BTServerHandler(btss.accept(),loc));
t.start();
Log.wtf("BTS","Found");
loc++;
}
} else {
Log.e("error", "Bluetooth is disabled.");
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
And here is my client thread which attempts to connect
private class BTClientThread implements Runnable{
#Override
public void run() {
try {
if (ad != null) {
if (ad.isEnabled()) {
Set<BluetoothDevice> bondedDevices = ad.getBondedDevices();
if (bondedDevices.size() > 0) {
Iterator<BluetoothDevice> iter = bondedDevices.iterator();
BluetoothDevice device = iter.next();
Log.wtf("dev", device.getName());
BluetoothSocket clientsocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
clientsocket.connect();
Log.wtf("Connected",device.getName());
}
Log.e("error", "No appropriate paired devices.");
} else {
Log.e("error", "Bluetooth is disabled.");
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
Hold your breath, here comes the weird part, the call btss.accept() hangs forever (Doesn't even return once), while at the same time, the client device connects somehow. When I call
BluetoothSocket clientsocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
clientsocket.connect()
This pops the toast on the phone which is hanging on accept saying "DeviceName connected" then after a while it pops another toast saying "DeviceName disconnected" on its own, without me doing ANYTHING, and at the same time the serverphone is still hanging on accept.
Here are my questions, why is it hanging on accept when the toast popped saying connected? And how could it possibly connect when the other phone is still listening for a connection?
Thanks for the help.
As it turns out, using that specific UUID caused a problem from some reason I still don't understand? After trying many random things, I finally decided to try another random UUID and that magically caused it to work.
Here is my new UUID
private UUID uuid = UUID.fromString("56e8a14a-80b3-11e5-8bcf-feff819cdc9f");
Is it possible to force android to check if an NFC tag is near? I'm only able to read the tag when android detects it, I would like to force it to check if a tag is near at a specific moment
What you want to do is in general not possible. However if you can live with a dirty hack the following will work (thanks to unspecified behaviour):
First disable the reader-mode of all supported tag types. This brings the NFC subsystem into a clean state, e.g. it makes sure that the NFC controller will have no connection to the tag.
Once done restore the reader-mode again. If a tag is present at that moment you will get the usual discovery action as an intent. It may take a second or two though.
Control of the reader-mode is possible using NfcAdapter.enableReaderMode and NfcAdapter.disableReaderMode
I figured out a bit of a hack for this that works (for me, at least!)
First, when you initially detect the tag via the android.nfc.action.NDEF_DISCOVERED, get the tag as a field in your class and start a timer (this is in C#/Xamarin but the same should apply for Java):
_tag = Intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
ReaderTimer = new Timer(2000);
ReaderTimer.Elapsed += TimerElapsed;
ReaderTimer.Start();
Now, every 2 seconds this will fire. It will attempt to reconnect to the tag. If it can't the tag is gone.:
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
if (_tag == null)
{
return;
}
Ndef ndef = Ndef.Get(_tag);
if (ndef == null)
{
// NDEF is not supported by this Tag.
return;
}
if (!ndef.IsConnected)
{
try
{
ndef.Close();
ndef.Connect();
}
catch (Exception ex)
{
// could not reconnect
// implies tag is not in proximity
//do whatever needs to be done when NFC is disconnected
ReaderTimer.Stop();
}
}
}
I've tested this with API 14.
Unfortunately when the screen is turned off ndef.Connect() fails, so that is registered as a disconnect.
Try this code and it works ! It will continuously check if the NFC tag is near to the phone or not.
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
readFromIntent(intent);
if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
checkNFCStatus();
handler.postDelayed(this,1000);
}
}, 1000);
}
}
public void checkNFCStatus(){
try {
if(myTag != null) {
Ndef ndefTag = Ndef.get(myTag);
ndefTag.connect();
if (ndefTag.isConnected()) {
Log.d("network", "NFC connected");
} else {
Log.d("network", "NFC disconnected");
}
ndefTag.close();
}
} catch (IOException e) {
e.printStackTrace();
Log.d("network", "NFC disconnected");
}
}
//If the connection is not closed, an exception will be thrown
I have been able to successfully cast video to a Chromecast and have the option let the video play when disconnecting and it all works great. However, if I choose to quit the application and let the video continue playing and then try to re-join the currently playing session and try to use the RemoteMediaPlayer to control the video I am getting: "java.lang.IllegalStateException: No current media session".
Just as a background, I am saving the route id and session id on the initial connect into preferences and am able to successfully call "Cast.CastApi.joinApplication" and when in the onResult I am recreating the Media Channel and setting the setMessageReceivedCallbacks like so:
Cast.CastApi.joinApplication(mApiClient,"xxxxxxxx",persistedSessionId).setResultCallback(new ResultCallback<Cast.ApplicationConnectionResult>() {
#Override
public void onResult(Cast.ApplicationConnectionResult applicationConnectionResult) {
Status status = applicationConnectionResult.getStatus();
if (status.isSuccess()) {
mRemoteMediaPlayer = new RemoteMediaPlayer();
mRemoteMediaPlayer.setOnStatusUpdatedListener(
new RemoteMediaPlayer.OnStatusUpdatedListener() {
#Override
public void onStatusUpdated() {
Log.d("----Chromecast----", "in onStatusUpdated");
}
});
mRemoteMediaPlayer.setOnMetadataUpdatedListener(
new RemoteMediaPlayer.OnMetadataUpdatedListener() {
#Override
public void onMetadataUpdated() {
Log.d("----Chromecast----", "in onMetadataUpdated");
}
});
try {
Cast.CastApi.setMessageReceivedCallbacks(mApiClient,mRemoteMediaPlayer.getNamespace(), mRemoteMediaPlayer);
} catch (IOException e) {
Log.e("----Chromecast----", "Exception while creating media channel", e);
}
//-----------RESOLUTION START EDIT------------------
mRemoteMediaPlayer.requestStatus(mApiClient).setResultCallback(new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
#Override
public void onResult(RemoteMediaPlayer.MediaChannelResult mediaChannelResult) {
Status stat = mediaChannelResult.getStatus();
if(stat.isSuccess()){
Log.d("----Chromecast----", "mMediaPlayer getMediaStatus success");
// Enable controls
}else{
Log.d("----Chromecast----", "mMediaPlayer getMediaStatus failure");
// Disable controls and handle failure
}
}
});
//-----------RESOLUTION END EDIT------------------
}else{
Log.d("----Chromecast----", "in status failed");
}
}
}
If I declare the RemoteMediaPlayer as static:
private static RemoteMediaPlayer mRemoteMediaPlayer;
I can join the existing session as well as control the media using commands like:
mRemoteMediaPlayer.play(mApiClient);
or
mRemoteMediaPlayer.pause(mApiClient);
But once I quit the application obviously the static object is destroyed and the app produces the aforementioned "No current media session" exception. I am definitely missing something because after I join the session and register the callback perhaps I need to start the session just like it was creating when I initially loaded the media using mRemoteMediaPlayer.load(.
Can someone please help as this is very frustrating?
The media session ID is part of the internal state of the RemoteMediaPlayer object. Whenever the receiver state changes, it sends updated state information to the sender, which then causes the internal state of the RemoteMediaPlayer object to get updated.
If you disconnect from the application, then this state inside the RemoteMediaPlayer will be cleared.
When you re-establish the connection to the (still running) receiver application, you need to call RemoteMediaPlayer.requestStatus() and wait for the OnStatusUpdatedListener.onStatusUpdated() callback. This will fetch the current media status (including the current session ID) from the receiver and update the internal state of the RemoteMediaPlayer object accordingly. Once this is done, if RemoteMediaPlayer.getMediaStatus() returns non-null, then it means that there is an active media session that you can control.
As user3408864 pointed out, requestStatus() after rejoining the session works. Here is how i managed to solve it in my case and it should work in yours.
if(MAIN_ACTIVITY.isConnected()){
if(MAIN_ACTIVITY.mRemoteMediaPlayer == null){
MAIN_ACTIVITY.setRemoteMediaPlayer();
}
MAIN_ACTIVITY.mRemoteMediaPlayer.requestStatus(MAIN_ACTIVITY.mApiClient).setResultCallback( new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
#Override
public void onResult(RemoteMediaPlayer.MediaChannelResult mediaChannelResult) {
if(playToggle ==0){
try {
MAIN_ACTIVITY.mRemoteMediaPlayer.pause(MAIN_ACTIVITY.mApiClient);
playToggle =1;
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
MAIN_ACTIVITY.mRemoteMediaPlayer.play(MAIN_ACTIVITY.mApiClient);
playToggle =0;
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
Ignore, MAIN_ACTIVITY, it is just a static reference to my activity since i run this piece of code from a Service. Also, setRemoteMediaPlayer() is a method where i create a new RemoteMediaPlayer() and attach the corresponding Listeners.
Hopefully this helps. Also, sorry if any mistake, it is my first post to StackOverFlow.
One part of my application connects to a device through Bluetooth and normally works fine but occasionally it won't connect and I get the following error
03-11 10:29:20.328: E/BluetoothComService(8059): accept() failed
03-11 10:29:20.328: E/BluetoothComService(8059): java.io.IOException: Operation Canceled
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothSocket.acceptNative(Native Method)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothSocket.accept(BluetoothSocket.java:316)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothServerSocket.accept(BluetoothServerSocket.java:105)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothServerSocket.accept(BluetoothServerSocket.java:91)
03-11 10:29:20.328: E/BluetoothComService(8059): at com.mypackage.name.bluetooth.BluetoothService$AcceptThread.run(BluetoothService.java:298)
This is the line where I get the exception
socket = mmServerSocket.accept();
And this is the complete AcceptThread
private class AcceptThread extends Thread {
// The local server socket
private BluetoothServerSocket mmServerSocket;
public boolean successInit = false;
public AcceptThread() {
closeAllConnections();
/*
* if(mmServerSocket != null) { try { mmServerSocket.close(); } catch
* (IOException e) { e.printStackTrace(); } }
*/
BluetoothServerSocket tmp = null;
// Create a new listening server socket
while (!successInit) {
try {
tmp = mAdapter
.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
successInit = true;
} catch (Exception e) {
successInit = false;
}
}
/*
* try { tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME,
* MY_UUID); successInit= true; } catch (IOException e) { Log.e(TAG,
* "listen() failed", e); tmp = null; successInit = false; }
*/
mmServerSocket = tmp;
}
public void run() {
if (D)
Log.d(TAG, "BEGIN mAcceptThread" + this);
setName("AcceptThread");
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mAdapter.cancelDiscovery();
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "accept() failed", e);
Log.e("Error", "This isn't connecting");
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (BluetoothService.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice());
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new
// socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (D)
Log.i(TAG, "END mAcceptThread");
}
public void cancel() {
if (D)
Log.d(TAG, "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of server failed", e);
}
}
}
Here is the function I call at the beginning of AcceptThread in hopes to close everything to restart it
public void closeAllConnections() {
if (mmInStream != null) {
try {mmInStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmOutStream != null) {
try {mmOutStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmSocket != null) {
try {
mmSocket.close();
//mmSocket.connect();
}
catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
I've read through the Bluetooth Docs and SO questions but I haven't found anything that works for me and it gets a bit confusing for me as this is my first time connecting through BT.
Note
The only "fix" I have found when this happens is to turn off the BT adapter, force close the program, restart BT adapter and restart app, which is not good for obvious reasons. I tried restarting the adapter programmatically but I still can't connect.
Can anyone see what might be wrong in my BlutoothService class, which is where AcceptThread is located? Or how I would go about resolving this issue? Thanks!
Update
It does, in fact, seem like the connection is sometimes closed on one Thread and trying to reconnect on another. The problem is that I can't figure out what would cause it to try and connect on a separate Thread or how to fix it when this happens.
The only way I can successfully reproduce this is if my BT device is turned off then I turn the BT adapter off. When I turn everything back on then I get the exception and cannot connect. I have customers that it happens to randomly and periodically so I'm hoping the issues are related.
Well, part of my problem was a hardware issue that was found out to be a problem on the third-party manufacturers end. They're firmware wasn't quite right and when it was reading the BT address, it was occasionally being corrupted.
On the software side, it was running the AcceptThread in two separate Threads periodically. What I did to fix that was to create a function to close the socket and input/output streams...
public void closeAllConnections()
{
if (mmInStream != null)
{
try {mmInStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmOutStream != null)
{
try {mmOutStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmSocket != null)
{
try {
mmSocket.close();
Log.e("TAG", "close() of connect socket successfu;");
} catch (IOException e) {
Log.e("TAG", "close() of connect socket failed", e);}
}
Then in the BluetoothCom class, I noticed it wasn't always checking for the BT object to be null before trying to restart the service.
private void setupService() {
// Initialize the BluetoothChatService to perform bluetooth connections
if((mChatService != null) && (mChatService.getState() != 0)) {
mChatService.stop();
}
// I didn't have this so it would always start a new instance of the Service
if (mChatService == null)
mChatService = new BluetoothService(mHandler);
mChatService.start();
}
This seems to have helped and I no longer have those problems. However, now testing on the Samsung Galaxy Tab 4 and I am once again having connection issues but only on this device. Maybe this information can help someone and I will update my answer if I figure anything else out with the new problem.
Note: As stated above, this Bluetooth app uses modified code from Android's BluetoothChat app.
Also, I have read (and noticed) that different manufacturers implement the BT stack differently which can lead to headaches (at least if yo don't know enough about it).
Although this is old post but I recently contact same issue so I want to write down the way I solve it.
It seems your code is from Google samples BlutoothChat (as it looks same, sorry if I misunderstand). I also create my own application that base on this sample (on API level 10). I meet the accept() fail issues if I try to connect one device to other device but at the end I solve this question by simply remove some code in MainActivty
On the Google samples main activity it contain many methods when activity change (Start, Pause, etc).
Original code have this
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
if (mChatService != null) {
if (mChatService.getState() == ChatService.STATE_NONE) {
mChatService.start();
}
}
}
This code start the Chat Service and running the AcceptThread to listening incoming connections.
When application start, this method will be call "once" and create the AcceptThread. If you do any other things that make the main activity onPause() pause (In Google samples case, if you click menu to start device_list activity the main activity will pause), when the application back to main activity it will call create AcceptThread method "one more time", this cause the problem because one thread already running but you try to interrupt it. And at the end happen accept() fail error and throw java.io.IOException: Operation Canceled error.
So to avoid this is simply remove the codes in OnResume()
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
}
or if you don't want delete any codes because you afraid cause some problem, put this code (mChatService != null) mChatService.stop(); in...
#Override
public synchronized void onPause() {
super.onPause();
if (mChatService != null) mChatService.stop();
if(D) Log.e(TAG, "- ON PAUSE -");
}
Both works perfect in my project. Method 1 not create the new thread if activity resume, and Method 2 kill all the thread if you leave the current activity and disconnect all current connections if you already have one (it will start the thread again once you turn back). Method 1 wouldn't return any error but method 2 will throw accept fail again if you leave the current activity, so I suggest to use method 1.
Need to notice that this error usually happen after you modify Google samples BlutoothChat, it will never appear on the original app.
I have seen many post talk about this issue, but not see any one come out with this answer, so just want to share this. Hope this is helpful.
That exception should occur when the BluetoothServerSocket is closed or garbage collected. I suspect that the exception is happening on an OLD copy of the thread. So something like: When you create the new thread the old thread gets cancelled and thus the BluetoothServerSocket is closed and thus accept correctly fails with that error. Check this in the debugger and/or logging on which thread the various events occur; e.g. set breakpoints on the line after accept and perhaps on the cancel function, then inspect the thread IDs there -- is the exception occurring on a previous thread?
Suppose phone finds open wi-fi network and connects to it. But wi-fi network is "inactive", i.e. when you open browser you see prompt for credentials. I have many apps on my phone(for example web-browser), which fail to work in such cases.
I want to send data using mobile network, but system still tries to use wi-fi.
NetworkInfo.isAvailable() and NetworkInfo.isConnected() still return true for the described wi-fi networks.
Any solution?
I've been having the same problem, and what I found is there is no such possibility via the Android SDK, you have to write your own way to do it.
It depends what do you want to do with the network and what do you mean by 'inactive' - you can be connected to a router, which doesn't have connection to the Internet, and there is no Android method to check such situation. As MrMichael wrote, ping is one way to check it, but in that case positive test gives you just info about ping - the network can have some heavy firewall which allows you to send pings, but i. e. will not let HTTP request through.
In that case, you have to write your own custom test for your own needs, alas - that's what I did. I just implemented simple ping-like protocol (I try to connect my socket on proper IP/port and send short message waiting for short answer). Only that gives me 100% warranty that the connection I want can be established.
As far as I am aware there is no way to force the use of a data connection over wifi (perhaps something that you shouldn't do without user interaction anyway).
I have the same requirements in many of my applications, I want to know if they have a viable network connection whilst the splash screen is loading (for example I show a read only version of the app if not).
The way that I get around this is to fire a simple service call to my server called isAlive which just returns a true imedialtly. This not only tells me that I am able to see my service, it also confirms that my server is on-line (no issues at my end). In the case that I do not get a response back in a timely fashion I inform the user that they have no network connection and "Please ensure you have a valid data/wifi connection before continuing". I then take the isConnected property for the wifi and modify this message to say "Your current Wireless connection does not internet access" or something similar.
Not quite the answer you were hoping for but maybe a possibility?
Just a suggestion: You may try using requestRouteToHost(). But first search SO for problems in using this method.
Also you'll need the CHANGE_NETWORK_STATE permission.
Try this....
I needed to do some custom work..but got it up and running...
My code switches from Wifi to Mobile network when its off.
And I am using the TimeService at port 37 to know that the Internet is DEAD while the wifi connection is still ON
//////////////////////////Edited//////////////////////////////////
Now i am putting here a complete working code i made. Please pardon me as the DRY (Don't Repeat Yourself Principle ) has been abused here. So please refactor the code and convert the duplicate codes into method , ie into a single sensible place, when using in production network
/////---------------------------Intial Available Network Checking
private boolean checkConnection(){
boolean connected = false;
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if ((ni.getTypeName().equalsIgnoreCase("WIFI")
|| ni.getTypeName().equalsIgnoreCase("MOBILE"))
& ni.isConnected() & ni.isAvailable()) {
connected = true;
}
}
}
return connected;
}
/////---------------------------Intial Available Network Checking
/////-------------------------------Check for the working Internet Connection
public boolean inetAddr(){
boolean x1 = false;
try {
Socket s = new Socket("utcnist.colorado.edu", 37);
InputStream i = s.getInputStream();
Scanner scan = new Scanner(i);
while(scan.hasNextLine()){
System.out.println(scan.nextLine());
x1 = true;
}
} catch (Exception e) {
x1 = false;
}
return x1;
}
/////-------------------------------Check for the working Internet Connection
////-------------------------------Check Mobile Conectivity Again
public boolean mobileConnect(){
boolean conn = false;
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNet = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(activeNet != null){
conn = true;
}else{
conn = false;
}
return conn;
}
////------------------------------Check Mobile Conectivity Again
Here i am using the Above Methods....
try{
if (!checkConnection()){
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
else{
if(inetAddr()){
aphandle = APIHandling.getInstance();
aphandle.xmlCreateSession();
System.out.println("Net Connectivity is Present");
DURATION = Integer.valueOf(getString(R.string.splash_duration));
splashHandler = new Handler();
// ================ Main Code of the Application
launcherRunnable = new Runnable() {
public void run() {
Intent i = new Intent(YumZingSplashActivity.this, YumZingTabHostActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
YumZingSplashActivity.this.finish();
}
};
if (DEBUG)
{
splashHandler.post(launcherRunnable);
}
else{
splashHandler.postDelayed(launcherRunnable, DURATION);
}
}
else{
if(mobileConnect()){
if(inetAddr()){
aphandle = APIHandling.getInstance();
aphandle.xmlCreateSession();
System.out.println("Net Connectivity is Present");
DURATION = Integer.valueOf(getString(R.string.splash_duration));
splashHandler = new Handler();
// ================ Main Code of the Application
launcherRunnable = new Runnable() {
public void run() {
Intent i = new Intent(YumZingSplashActivity.this, YumZingTabHostActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
YumZingSplashActivity.this.finish();
}
};
if (DEBUG)
{
splashHandler.post(launcherRunnable);
}
else{
splashHandler.postDelayed(launcherRunnable, DURATION);
}
}else{
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
}else{
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(YumZingSplashActivity.this);
myAlertDialog.setTitle("--- Connectivity Check ---");
myAlertDialog.setMessage("No Internet Connectivity");
myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YumZingSplashActivity.this.finish();
//splashHandler.removeCallbacks(launcherRunnable);
}});
System.out.println("No Internet Connectivity");
myAlertDialog.show();
}
}
}
//setContentView(R.layout.yumzing_splash_layout);
} catch(Exception ex){
System.out.println("Leak ko catch");
}
}
You could connect to the wifi network, try connect to any page in background and verify if there is any redirection. If so, it is very likely to be the credential pages. In fact when I was trying to find how to implement the solution I have just described, I found it to be described in HttpURLConnection class documentation at Android developers site. There you can read:
Handling Network Sign-On
Some Wi-Fi networks block Internet access until the user clicks through a sign-on page. Such sign-on pages are typically presented by using HTTP redirects. You can use getURL() to test if your connection has been unexpectedly redirected. This check is not valid until after the response headers have been received, which you can trigger by calling getHeaderFields() or getInputStream(). For example, to check that a response was not redirected to an unexpected host:
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
if (!url.getHost().equals(urlConnection.getURL().getHost())) {
// we were redirected! Kick the user out to the browser to sign on?
...
} finally {
urlConnection.disconnect();
}
}
Try
InetAddress.getByName(host).isReachable(timeOut)