I have an app that crashes when the wifi on phone goes out of range. It gets strings from an online txt mainly and I do disconnect the HTTPURLConnection after it gets done, so I was not expecting the crash. Below is the relevant code;
To check network availablity(all code that uses an internet connection gets checked by this first):
public boolean isNetworkAvailable() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
//if (netInfo != null && netInfo.isConnected()) {
return true;
}
return false;
}
My checkForPromptPassword asynctask that runs on onResume:
private class CheckForPromptPasswordAgain extends AsyncTask<Void, Void, Boolean>
{
// ProgressDialog pdLoading = new ProgressDialog(MainScreenActivity.this);
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
// pdLoading.setMessage("\tFetching Database...");
// pdLoading.show();
}
#Override
protected Boolean doInBackground(Void... params) {
//this method will be running on background thread so don't update UI frome here
//do your long running http tasks here,you dont want to pass argument and u can access the parent class' variable url over here
//view GONE by default of update button
if (isNetworkAvailable()){
if (PromptForPasswordAgain()){
//TODO: //show update button or dialog
return true;
}else{
//TODO: //proceed as normal
return false;
}
}
return false;
}
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
//this method will be running on UI thread
if (result==true){
promptForPassword();
}else{
// showDialog("string", "string",0);
}
// pdLoading.dismiss();
}
}
My checkForUpdate AsyncTask that runs on OnResume():
Private class CheckForUpdate extends AsyncTask<Void, Void, Boolean>
{
// ProgressDialog pdLoading = new ProgressDialog(MainScreenActivity.this);
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
// pdLoading.setMessage("\t string.");
// pdLoading.show();
}
#Override
protected Boolean doInBackground(Void... params) {
//this method will be running on background thread so don't update UI frome here
//do your long running http tasks here,you dont want to pass argument and u can access the parent class' variable url over here
//view GONE by default of update button
if (fileExistance("data.txt")){
try {
if (isNetworkAvailable()){
if (isDatabaseContentDifferent()){
//TODO: //show update button or dialog
return true;
}else{
//TODO: //proceed as normal
return false;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
Log.i("error","file data.txt does not exist in internal");
return false;
}
return false;
}
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
//this method will be running on UI thread
Button updateButton = (Button) findViewById(R.id.UpdateDatabase);
updateButton.setVisibility(View.GONE);
if (result==true){
showDialog("Database Updated On Server", "The Database App has detected a change in the database, press \"Update Database\" to account for the change(s). ",0);
updateButton.setVisibility(View.VISIBLE);
}else{
updateButton.setVisibility(View.GONE);
// showDialog("No Update Detected", "The Database App has detected a change in the database, press \"Update Database\" to account for the change(s). ",0);
}
// pdLoading.dismiss();
}
}
Example of the HTTPURLClient that I am using, many functions but this is the basic structure:
public boolean isDatabaseContentDifferent() throws IOException{
String page = null;
try{
URL url = new URL(_data);
HttpURLConnection.setFollowRedirects(true);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(false);
con.setReadTimeout(20000);
con.setRequestProperty("Connection", "keep-alive");
//get etag for update check
//String etag= "";
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0");
((HttpURLConnection) con).setRequestMethod("GET");
//System.out.println(con.getContentLength()) ;
con.setConnectTimeout(5000);
BufferedInputStream in = new BufferedInputStream(con.getInputStream());
//make seperate function for etag it doesn't work with GET
//String etag = con.getHeaderField("etag");
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
System.out.println(responseCode);
}
StringBuffer buffer = new StringBuffer();
int chars_read;
//int total = 0;
while ((chars_read = in.read()) != -1)
{
char g = (char) chars_read;
buffer.append(g);
}
page = buffer.toString();
//create password.txt to internal
//TODO: checkkk
con.disconnect();
}catch(Exception e){
showDialog("Database Fetch Failure","Unable to Fetch Password Database, check your internet" +
" connection and try again later.",0);
Log.i("Page", "Error in isDatabaseContentDifferent()");
return false;
}
if (fileExistance("data.txt")){
if (isTextInFileDifferent(page,"data.txt")){
return true;
}else{
return false;
}
}else{
Log.i("Page","file data.txt does not exist IN isDatabaseContentDifferent()");
return false;
}
}
Any help will be highly appreciated. Thanks.
Related
I need a service in the background that constantly pings google. But I have no idea how to do it. I am new here. My method does not work does not repeat. It only works once and it always returns "false" .
isConnectedToServer function
public boolean isConnectedToServer(String url, int timeout) {
try{
URL myUrl = new URL(url);
URLConnection connection = myUrl.openConnection();
connection.setConnectTimeout(timeout);
connection.connect();
return true;
} catch (Exception e) {
// Handle your exceptions
return false;
}}
onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(isConnectedToServer("http://www.google.com",3000)){
Toast.makeText(this, "Okay", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "Not Okay", Toast.LENGTH_SHORT).show();
}}
Manifest
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
I see Not Okay once on the screen. Only once. Even when I have an internet connection. What can I do about it?
try this create a class that extends AsyncTask
public class CheckInternet extends AsyncTask<Void, Void, Boolean>{
private static final String TAG = "CheckInternet";
private Context context;
public CheckInternet(Context context) {
this.context = context;
}
#Override
protected Boolean doInBackground(Void... voids) {
Log.d(TAG, "doInBackground: ");
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
if (isConnected) {
if ( executeCommand()) return true;
}
return false;
}
private boolean executeCommand(){
System.out.println("executeCommand");
Runtime runtime = Runtime.getRuntime();
try
{
Process mIpAddrProcess = runtime.exec("/system/bin/ping -c "+"www.google.com");
int mExitValue = mIpAddrProcess.waitFor();
System.out.println(" mExitValue "+mExitValue);
if(mExitValue==0){
return true;
}else{
return false;
}
}
catch (InterruptedException ignore)
{
ignore.printStackTrace();
System.out.println(" Exception:"+ignore);
}
catch (IOException e)
{
e.printStackTrace();
System.out.println(" Exception:"+e);
}
return false;
}
I have this class where it process XML and store it inside an ArrayList<FeedItem>. I can display the array content in the method where I store the data but when I try to display the array in another method it did not pass the if checking indicating that the ArrayList is empty. Because of this, I can't create a ListView because it'll return the same error. I hope someone can briefly explain to me what is wrong.
ReadRSS.java
public class ReadRSS extends AsyncTask<Void, Void, Void> {
//Initialize progress dialog
Context context;
String address;
ProgressDialog progressDialog;
XmlPullParserFactory xmlPullParserFactory;
volatile boolean parsingComplete = true;
ArrayList<FeedItem> feedItems;
ListView listView;
public ReadRSS(Context context, ListView listView, String retrieveAddress) {
//Create a new progress dialog
this.listView = listView;
this.address = retrieveAddress;
this.context = context;
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Loading....");
}
// Runs in UI before background thread is called
#Override
protected void onPreExecute() {
//Display progress dialog
progressDialog.show();
super.onPreExecute();
}
// This is run in a background thread
#Override
protected Void doInBackground(Void... voids) {
fetchXML();
return null;
}
// This is called from background thread but runs in UI
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
// This runs in UI when background thread finishes
#Override
protected void onPostExecute(Void aVoid) {
//Dismiss progress dialog
super.onPostExecute(aVoid);
progressDialog.dismiss();
/*if(listView != null) {
CustomAdapter customAdapter = new CustomAdapter(context, R.layout.activity_listview, feedItems);
listView.setAdapter(customAdapter);
}*/
if(feedItems != null){
//Gives error
for(int i = 0; i < feedItems.size(); i++) {
Log.d("Title", feedItems.get(i).getTitle());
Log.d("Date", feedItems.get(i).getPubDate());
}
}
}
//New Build
public void parseXMLAndStoreIt(XmlPullParser myParser) {
int event;
String text;
String title = null;
String date = null;
feedItems = new ArrayList<FeedItem>();
try {
event = myParser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
String tagName = myParser.getName();
switch (event){
case XmlPullParser.START_TAG:
if(tagName.equalsIgnoreCase("item")){
int eventChild = myParser.next();
//int innerLoop = 1;
String tagNameChild = "";
while(eventChild != XmlPullParser.END_DOCUMENT){
if(eventChild == XmlPullParser.START_TAG){
tagNameChild = myParser.getName();
// Output Test
//Log.d("Tag ", tagNameChild);
}
else if (eventChild == XmlPullParser.TEXT){
text = myParser.getText();
// Output Test
//Log.d("Test ", text);
if(tagNameChild.equalsIgnoreCase("title")){
title = text;
// Output Test
//Log.d("Title ", myParser.getText());
}
else if(tagNameChild.equalsIgnoreCase("pubDate")){
date = text;
// Output Test
//Log.d("PubDate ", myParser.getText());
}
}
else if (eventChild == XmlPullParser.END_TAG){
if(myParser.getName().equalsIgnoreCase("item")){
feedItems.add(new FeedItem(title,date));
// Output Test
//Log.d("Test ", title);
}
tagNameChild = "";
}
eventChild = myParser.next();
//innerLoop++;
}
//Output Test
/*for(int i = 0; i < feedItems.size(); i++) {
Log.d("Title", feedItems.get(i).getTitle());
Log.d("Date", feedItems.get(i).getPubDate());
}*/
}
break;
case XmlPullParser.TEXT:
break;
case XmlPullParser.END_TAG:
break;
}
event = myParser.next();
}
parsingComplete = false;
}
catch (Exception e) {
e.printStackTrace();
}
}
public void fetchXML(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
URL url = new URL(address);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 );
conn.setConnectTimeout(15000 );
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
xmlPullParserFactory = XmlPullParserFactory.newInstance();
XmlPullParser myparser = xmlPullParserFactory.newPullParser();
myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
myparser.setInput(stream, null);
parseXMLAndStoreIt(myparser);
stream.close();
}
catch (Exception e) {
}
}
});
thread.start();
}
}
You are calling fetchXML() from doInBackground, but fetchXML() starts a new thread and then immediately returns. Then doInBackground() immediately returns and onPostExecute() is called. However, at that point, the thread launched by fetchXML() has not had time to finish, so feedItems has not been properly set.
That's the wrong way to use an AsyncTask. Instead, you should do the fetching directly in the doInBackground() thread. Just rewrite fetchXML() to do the fetching itself, rather than launch a separate thread to do the fetching.
SO currently i have an AsyncTask class that runs and POST's data to my server when I click a button(which works great).
What im trying to do now is handle what happens when the user is not connected to the internet. so i have set up these classes to notify the app when internet has connected so that the data can be sent automatically to the server.
AsyncTask class(inner class)
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
ProgressDialog dialog = new ProgressDialog(getActivity());
final AlertDialog finishedDialog = new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setPositiveButton(android.R.string.ok, null)
.create();
#Override
protected String doInBackground(String... urls) {
onProgressUpdate("Uploading Data...");
return POST(urls[0]);
}
#Override
protected void onPreExecute() {
this.dialog.show();
finishedDialog.setOnShowListener(new DialogInterface.OnShowListener(){
#Override
public void onShow(DialogInterface dialog) {
Button b = finishedDialog.getButton(AlertDialog.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// navigate to match summary.....
finishedDialog.dismiss();
}
});
}
});
}
protected void onProgressUpdate(String msg) {
dialog.setMessage(msg);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
if (result != ""){
finishedDialog.setTitle("Upload Complete!");
finishedDialog.setMessage("Data Sent Successfully");
finishedDialog.show();
dialog.dismiss();
editor.clear();
editor.commit();
//Toast.makeText(getActivity().getBaseContext(), result, Toast.LENGTH_LONG).show();
}else
{
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
finishedDialog.setTitle("Upload Failed!");
finishedDialog.setMessage("Data Will Automatically Be Uploaded When Internet Connection Is Available");
finishedDialog.show();
dialog.dismiss();
}}, 1000);
setFlag(true);
}
}
}
public static boolean getFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public String POST(String url){
InputStream inputStream = null;
String result = "";
try {
// 1. create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// 2. make POST request to the given URL
HttpPost httpPost = new HttpPost(url);
if(adapter.updateNeeded()){
JSONObject main = new JSONObject(exmaplePrefs.getString("jsonString", "cant find json"));
JSONObject dbUpdates = new JSONObject(exmaplePrefs.getString("ChangesJSON", "cant find Changejson"));
main.put("Team_Updates", dbUpdates);
json = main.toString();
}else{
json = exmaplePrefs.getString("jsonString", "cant find json");
// String json = "{\"twitter\":\"test\",\"country\":\"test\",\"name\":\"test\"}";
}
// 5. set json to StringEntity
StringEntity se = new StringEntity(json);
se.setContentType("application/json;charset=UTF-8");
// 6. set httpPost Entity
httpPost.setEntity(se);
// 7. Set some headers to inform server about the type of the content
// httpPost.setHeader("Accept", "application/json");
// httpPost.setHeader("Content-type", "application/json");
// httpPost.setHeader("json", json);
// 8. Execute POST request to the given URL
HttpResponse httpResponse = httpclient.execute(httpPost);
// 9. receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
String status = httpResponse.getStatusLine().toString();
// 10. convert inputstream to string
if (!status.equals("HTTP/1.1 500 Internal Server Error")){
if(inputStream != null){
result = convertInputStreamToString(inputStream);
}
else{
result = "Did not work!";
}
}else{
System.out.println("500 Error");
}
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
System.out.println("eerroorr "+e);
}
// 11. return result
System.out.println(result);
return result;
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
}
NetworkUtil class
public class NetworkUtil {
public static int TYPE_WIFI = 1;
public static int TYPE_MOBILE = 2;
public static int TYPE_NOT_CONNECTED = 0;
public static int getConnectivityStatus(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (null != activeNetwork) {
if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
return TYPE_WIFI;
if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
return TYPE_MOBILE;
}
return TYPE_NOT_CONNECTED;
}
public static String getConnectivityStatusString(Context context) {
int conn = NetworkUtil.getConnectivityStatus(context);
String status = null;
if (conn == NetworkUtil.TYPE_WIFI) {
status = "Wifi enabled";
} else if (conn == NetworkUtil.TYPE_MOBILE) {
status = "Mobile data enabled";
} else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
status = "Not connected to Internet";
}
return status;
}
}
BroadcastReceiver class
public class NetworkChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
intent.getExtras();
String status = NetworkUtil.getConnectivityStatusString(context);
Toast.makeText(context, status, Toast.LENGTH_LONG).show();
if(MatchFragment.getFlag()){
//send data
}
}
}
So in the BroadcastReceiver class I check the flag that gets set to true when the app attempts to send data but there is not internet (onPostExecute in AsyncTask Class).
so what want to do is some how call the POST method. do i have to create a new Async task class? Im a bit stumped here .
Thanks
Using AsyncTask in BroadcastReceiver is a bad practice.
You should use Service because Android OS may kill your process or onReceive() may run to completion before asyncTask will return result, so there is no guarantee you will get the expected result.
You shouldn't use AsyncTask in Broadcast Receiver because the system can kill your process after returning from onReceive method (if there is no any active service or activity).
Proof link
Official documentation recommends IntentService for such cases (see paragraph about Broadcast Receivers).
The other answers are not correct according to Google's documentation. The Broadcast Receivers developer guide explicitly calls out that you can use AsyncTasks from BroadcastReceivers if you call goAsync() first and report the status to the pending result in the AsyncTask
For this reason, you should not start long running background threads from a broadcast receiver. After onReceive(), the system can kill the process at any time to reclaim memory, and in doing so, it terminates the spawned thread running in the process. To avoid this, you should either call goAsync() (if you want a little more time to process the broadcast in a background thread) or schedule a JobService from the receiver using the JobScheduler, so the system knows that the process continues to perform active work.
And later it clarifies how much time you actually get:
Calling goAsync() in your receiver's onReceive() method and passing
the BroadcastReceiver.PendingResult to a background thread. This keeps
the broadcast active after returning from onReceive(). However, even
with this approach the system expects you to finish with the broadcast
very quickly (under 10 seconds). It does allow you to move work to
another thread to avoid glitching the main thread.
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
#Override
public void onReceive(final Context context, final Intent intent) {
final PendingResult pendingResult = goAsync();
AsyncTask<String, Integer, String> asyncTask = new AsyncTask<String, Integer, String>() {
#Override
protected String doInBackground(String... params) {
StringBuilder sb = new StringBuilder();
sb.append("Action: " + intent.getAction() + "\n");
sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
Log.d(TAG, log);
// Must call finish() so the BroadcastReceiver can be recycled.
pendingResult.finish();
return data;
}
};
asyncTask.execute();
}
}
I've an Android app that has a login capabilities, and the login box has a TextView that displays messages to the user when trying to login(ie. wrong name, wrong pass, etc..).
I have two methods, the first one check if the fields is filled or not, and if filled it redirects the app to the second method that will check the user/pass from the local server.
the problem is when resetting the text in the second method, as when i set the text at the first method everything is OK, but when changing it in the second method it doesn't change, I can set it like million times in the first method and everything going well, another thing is when i set the text at the first time from the second method it works perfectly.
Hint1: this first method is the onClick method of an OnClickListener.
Hint2: the printed log is prented like million times in the logcat so the while condition verified
public class Login extends Activity {
public EditText user, pw;
public TextView errorMessage;
private static String response = null;
private static String data;
the first method :
public void onClick(View v) {
if (v == login) {
String userName = Login.this.user.getText().toString();
String Password = Login.this.pw.getText().toString();
if (userName.equals(null_string)
|| Password.equals(null_string)) {
errorMessage.setText(R.string.request);
} else {
protocol = protocol_login;
boolean status = false;
try {
status = checkLogin(userName, Password);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (status) {
Intent intent = new Intent(v.getContext(),
MainPage.class);
go(intent);
} else {
errorMessage.setText(R.string.login_error);
}
}
}
}
the second method:
private String connect(String data) throws UnknownHostException,
IOException, JSONException {
setData(data);
Thread connect = new Thread(new ConnectToServer(getData()));
connect.start();
while (response == null) {
System.out.println("waiting");
errorMessage.setText(R.string.waiting);
}
return response;
}
}
Your problem lies in the fact that in the second method you are trying to update the GUI while actually being a second thread.
U can use the runOnUIThread method
Activity.runOnUiThread(new Runnable() {
#Override
public void run() {
errorMessage.setText(R.string.waiting);
}
});
while (response == null) {
System.out.println("waiting");
}
U also shouldn't set the text in a while-loop if the text isn't changing so you don't use unnecessary resources.
I'm not sure what exactly is causing your problem (you are blocking the UI thread somewhere), but there are better ways of getting a response from the server. You are essentially synchronously checking for an asynchronous response (below), because you are continuously polling whether response is not null.
Android has a useful class called AsyncTask. You give an AsyncTask some work to do on a background thread (what ConnectToServer(..) does), and when it is done, another method on the AsyncTask (called onPostExecute(..)) is called. The benefit of this over your approach is that it handles all the threading for you, and doesn't poll. There is also a method onPreExecute() which you would set your waiting text in.
N.B. checking synchronously for an asynchronous response
What I mean by this is that the response can come back at any time (asynchronously), yet you are checking for it at any point you can (synchronously). This is going to waste valuable resources on the CPU - you should get the response to tell you when it is finished rather than continually ask whether it is.
First, these two string variables are declared globally:
String userName,Password
Try this easy Asyntask method:
private class SetDataOfWebService extends AsyncTask<Void, Void,Boolean> {
ProgressDialog pDialog;
boolean success = false;
ConnectivityManager connectivity;
#Override
protected void onPreExecute() {
pDialog = new ProgressDialog(MailSettings.this);
pDialog.setMessage("Please Wait..");
pDialog.show();
}
#Override
protected Boolean doInBackground(Void... params) {
if (isNetworkAvailable()) {
success = true;
if (userName.length()>0 || Password.length()>0) {
status = checkLogin(userName, Password);
}
else
{
errorMessage.setText(R.string.request);
}
} else {
success = false;
}
return success;
}
#Override
protected void onPostExecute(Boolean result) {
if (pDialog != null && pDialog.isShowing())
pDialog.dismiss();
if (result) {
if (status) {
Intent intent = new Intent(v.getContext(),
MainPage.class);
go(intent);
} else {
errorMessage.setText(R.string.login_error);
}
} else {
return;
}
}
public boolean isNetworkAvailable() {
connectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
Log.i("Class", info[i].getState().toString());
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
}
////Calling This Function On Button CLick Like This
userName = Login.this.user.getText().toString();
Password = Login.this.pw.getText().toString();
new SetDataOfWebService().execute();
I am trying to write a part in my app that will differentiate between an Active Wifi connection and an actual connection to the internet. Finding out if there is an active Wifi connection is pretty simple using the connection manager however every time I try to test if I can connect to a website when the Wifi is connected but there is no internet connection I end up in an infinite loop.
I have tried to ping google however this ends up the same way:
Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = 5;
try {
returnVal = p1.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean reachable = (returnVal==0);
return reachable;
I also tried this code:
if (InetAddress.getByName("www.xy.com").isReachable(timeout))
{ }
else
{ }
but I could not get isReachable to work.
It does works for me:
To verify network availability:
private Boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();
}
To verify internet access:
public Boolean isOnline() {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
return reachable;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
I use this:
public static void isNetworkAvailable(Context context){
HttpGet httpGet = new HttpGet("http://www.google.com");
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
try{
Log.d(TAG, "Checking network connection...");
httpClient.execute(httpGet);
Log.d(TAG, "Connection OK");
return;
}
catch(ClientProtocolException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
Log.d(TAG, "Connection unavailable");
}
It comes from an other stackoverflow answer but I can't find it.
EDIT:
Finally I found it: https://stackoverflow.com/a/1565243/2198638
Here is some modern code that uses an AsynTask to get around an issue where android crashes when you try and connect on the main thread and introduces an alert with a rinse and repeat option for the user.
class TestInternet extends AsyncTask<Void, Void, Boolean> {
#Override
protected Boolean doInBackground(Void... params) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
return true;
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return false;
}
#Override
protected void onPostExecute(Boolean result) {
if (!result) { // code if not connected
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("An internet connection is required.");
builder.setCancelable(false);
builder.setPositiveButton(
"TRY AGAIN",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
new TestInternet().execute();
}
});
AlertDialog alert11 = builder.create();
alert11.show();
} else { // code if connected
doMyStuff();
}
}
}
...
new TestInternet().execute();
To check if the android device is having an active connection, I use this hasActiveInternetConnection() method below that (1) tries to detect if network is available and (2) then connect to google.com to determine whether the network is active.
public static boolean hasActiveInternetConnection(Context context) {
if (isNetworkAvailable(context)) {
if (connectGoogle()) {
return true;
} else { //one more try
return connectGoogle();
}
} else {
log("No network available! (in hasActiveInternetConnection())");
return false;
}
}
public static boolean isNetworkAvailable(Context ct) {
ConnectivityManager connectivityManager = (ConnectivityManager) ct.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null;
}
public static boolean connectGoogle() {
try {
HttpURLConnection urlc = (HttpURLConnection)(new URL("http://www.google.com").openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(10000);
urlc.connect();
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
log("IOException in connectGoogle())");
return false;
}
}
Query a website like this:
Make your class implement AsyncTaskCompleteListenere<Boolean> by adding the following method to your class:
#Override
public void onTaskComplete(Boolean result) {
Toast.makeText(getApplicationContext(), "URL Exist:" + result, Toast.LENGTH_LONG).show();
// continue your job
}
Add a simple testConnection method to your class to be called when you want to check for your connectivity:
public void testConnection() {
URLExistAsyncTask task = new URLExistAsyncTask(this);
String URL = "http://www.google.com";
task.execute(new String[]{URL});
}
And finally the URLExistAsyncTask class which perform the connectivity test as an asynchronous (background) task and calls back your onTaskComplete method once done:
public class URLExistAsyncTask extends AsyncTask<String, Void, Boolean> {
AsyncTaskCompleteListenere<Boolean> callback;
public URLExistAsyncTask(AsyncTaskCompleteListenere<Boolean> callback) {
this.callback = callback;
}
protected Boolean doInBackground(String... params) {
int code = 0;
try {
URL u = new URL(params[0]);
HttpURLConnection huc = (HttpURLConnection) u.openConnection();
huc.setRequestMethod("GET");
huc.connect();
code = huc.getResponseCode();
} catch (IOException e) {
return false;
} catch (Exception e) {
return false;
}
return code == 200;
}
protected void onPostExecute(Boolean result){
callback.onTaskComplete(result);
}
}
I did use this method. It worked for me! For people who want to get the real Internet!
public boolean isOnline() {
try {
HttpURLConnection httpURLConnection = (HttpURLConnection)(new URL("http://www.google.com").openConnection());
httpURLConnection.setRequestProperty("User-Agent", "Test");
httpURLConnection.setRequestProperty("Connection", "close");
httpURLConnection.setConnectTimeout(10000);
httpURLConnection.connect();
return (httpURLConnection.getResponseCode() == 200);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
For doing this method every time! Just use a receiver
and =>
httpURLConnection.getResponseCode() == 200
This means the Internet is connected!
You can do it by create new parallel thread that count time :
final class QueryClass {
private int responseCode = -1;
private String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
if(url == null) {
return null;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(5000 );
urlConnection.setConnectTimeout(5000 );
Thread thread = new Thread() {
#Override
public void run() {
super.run();
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(responseCode == -1) {
//Perform error message
Intent intent = new Intent(context,ErrorsActivity.class);
intent.putExtra("errorTextMessage",R.string.errorNoInternet);
intent.putExtra("errorImage",R.drawable.no_wifi);
context.startActivity(intent);
}
}
};
thread.start();
urlConnection.connect();
responseCode = urlConnection.getResponseCode();
if (responseCode == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
}