How to stop HttpURLConnection.getInputStream()? - java

Below is my code:
private HttpURLConnection connection;
private InputStream is;
public void upload() {
try {
URL url = new URL(URLPath);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
is = connection.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopupload() {
connection = null;
is = null;
}
When I upload file, the line is = connection.getInputStream(); will spend a lot of time to get reply. So I want to implement a stop function as stopupload(). But if I call stopupload() while the code is handling at line is = connection.getInputStream();, it still needs to wait for its reply.
I want to stop waiting at once while implement stopupload(). How can I do it?

But if I call stopupload() while the code is handling at line is =
connection.getInputStream();, it still needs to wait for its reply.
Starting from HoneyComb, all network operations are not allowed to be executed over main thread. To avoid getting NetworkOnMainThreadException, you may use Thread or AsyncTask.
I want to stop waiting at once while implement stopupload(). How can I
do it?
Below code gives the user to stop uploading after 2 seconds, but you can modify the sleep times (should be less than 5 seconds) accordingly.
upload:
public void upload() {
try {
URL url = new URL(URLPath);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
// run uploading activity within a Thread
Thread t = new Thread() {
public void run() {
is = connection.getInputStream();
if (is == null) {
throw new RuntimeException("stream is null");
}
// sleep 2 seconds before "stop uploading" button appears
mHandler.postDelayed(new Runnable() {
public void run() {
mBtnStop.setVisibility(View.VISIBLE);
}
}, 2000);
}
};
t.start();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (connection != null) {
connection.disconnect();
}
}
}
onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
// more codes...
Handler mHandler = new Handler();
mBtnStop = (Button) findViewById(R.id.btn_stop);
mBtnStop.setBackgroundResource(R.drawable.stop_upload);
mBtnStop.setOnClickListener(mHandlerStop);
mBtnStop.setVisibility(View.INVISIBLE);
View.OnClickListener mHandlerStop = new View.OnClickListener() {
#Override
public void onClick(View v) {
stopUpload(); // called when "stop upload" button is clicked
}
};
// more codes...
}

private HttpURLConnection connection;
private InputStream is;
public void upload() {
try {
URL url = new URL(URLPath);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
Thread t = new Thread() {
public void run() {
is = connection.getInputStream();
}
};
t.start()
} catch (Exception e) {
e.printStackTrace();
}catch (InterruptedException e) {
stopupload(connection ,is, t);
}
}
public void stopupload(HttpURLConnection connection ,InputStream is,Thread t) {
if(connection != null ){
try {
t.interupt();
running = false;
connection=null;
is=null;
} catch (Exception e) {
}
}
}

Wrap the code that uses HttpURLConnection inside a Future, as described here.

Related

Cannot show the Toast through the Callback function

Here is the httpPost to send the data to server and get the response.
public void httpPost(String URL ) {
new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
int responseCode = connection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
stringBuilder.setLength(0);
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
callback.success(stringBuilder.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
Here is the Callback function to setup the string from server response.
public interface Callback{
void success(String string);
}
Click the button and post the data to server. Here can get the response of the string from Callback function but it cannot show the toast.
button.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View view) {
server.httpPost("https://google.com/index.php?username=Peter");
server.callback =new Server.Callback() {
#Override
public void success(String response) {
Log.d("test",response);
Toast.makeText(AddActivity.this, response,Toast.LENGTH_SHORT).show();
}
};
}
});
You must run the Toast on UI thread using the following code:
<Activity>.runOnUiThread(new Runnable() {
#Override
public void run() {
(Toast and other UI changes here...)
}
});

App crashes when connection is lost while using HttpUrlConnection

i'm making a class that get json data from an external url, it is working fine if there is a connection. also shows an error if there isn't.
the problem is if the connection lost while the class is getting data the app crashes.
here is my code:
//I always check connection before calling the class
class GetPost extends AsyncTask<String, String, String>
{
Context c;
String res;
public GetPost(Context c){
this.c=c;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
Earn.statu.setText("Loading post...");
}
#Override
protected String doInBackground(String[] p1)
{
try{
URL u = new URL(p1[0]);
HttpURLConnection con = (HttpURLConnection) u.openConnection();
InputStream is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
res = br.readLine();
}
catch (MalformedURLException e){}
catch (IOException e){}
return res;
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
try{
JSONObject jo = new JSONObject(res);
Earn.getVideoData(c,
jo.getString("pid"),
jo.getInt("duration"),
jo.getInt("id")
);
}catch(JSONException a){}
}
so guys is there any solution to prevent the app from crashing?
Set timeout on request by example:
try {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("HEAD");
con.setConnectTimeout(5000); //set timeout to 5 seconds
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
} catch (java.net.SocketTimeoutException e) {
return false;
} catch (java.io.IOException e) {
return false;
}

How can I delay a funtion call? [duplicate]

This question already has answers here:
How to call a method after a delay in Android
(35 answers)
Closed 4 years ago.
public class NotificationReceivedCheckDelivery extends NotificationExtenderService {
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult receivedResult) {
OverrideSettings overrideSettings = new OverrideSettings();
overrideSettings.extender = new NotificationCompat.Extender() {
#Override
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
// Sets the background notification color to Yellow on Android 5.0+ devices.
return builder.setColor(new BigInteger("FFFFEC4F", 16).intValue());
}
};
OSNotificationDisplayedResult displayedResult = displayNotification(overrideSettings);
Log.d("ONES",receivedResult.payload.title);
JSONObject AdditionalData = receivedResult.payload.additionalData;
Log.d("Adata",AdditionalData.toString());
String uuid= null;
try{
// {"uuid":"adddd"}
uuid = AdditionalData.getString("uuid");
}
catch (JSONException e){
Log.e("Error JSON","UUID",e);
}
// Create Object and call AsyncTask execute Method
new FetchNotificationData().execute(uuid);
return true;
}
private class FetchNotificationData extends AsyncTask<String,Void, String> {
#Override
protected String doInBackground(String... uuids) {
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String forecastJsonStr = null;
try {
URL url = new URL("http://test.com/AppDeliveryReport?uuid="+uuids[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
return forecastJsonStr;
} catch (IOException e) {
Log.e("PlaceholderFragment", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.i("json", s);
}
}
}
I want to delay calling the FetchNotificationData function with a random seconds.
This is a delivery report url request function. Whenever a notification from onesignal received at the app it will call the url. I don't want to blast the server with huge request at once. So I want to delay call with random seconds so that server will have to serve few calls on a given time.
You can use handler to delay call to function
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(Splash.this, "I will be called after 2 sec",
Toast.LENGTH_SHORT).show();
//Call your Function here..
}
}, 2000); // 2000 = 2 sec
you can use Handler like this
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// your FetchNotificationData function
}
},timeInMiliSec);
just remember to import Handler as android.os, not java.util.logging
timer = new Timer();
final int FPS = 3;
TimerTask updateBall = new UpdateBallTask();
timer.scheduleAtFixedRate(updateBall, 0, 1000 * FPS);
class:
class UpdateBallTask extends TimerTask {
public void run() {
// do work
}
}
///OR
final Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
handler.postDelayed(this, 100);
// do work
handler.removeCallbacksAndMessages(null);
}
};
handler.postDelayed(r, 100);

background and run continuous without close

I make mobile lost gps tracking application, that code will be running in only activity..
my application strategy is.
1) if found http://192.168.43.164/imei_000000000000000.txt file then find
"track" or "find_mobile" string in imei_000000000000000.txt.
2) if "track" or "find_mobile" string is found in imei_000000000000000.txt file then post
"http://192.168.43.164/add.php?long_itude=22.00023&lat_itude=22.00023." link
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
final ArrayList<String> urls = new ArrayList<String>();
try{
URL url = new URL("http://192.168.43.164/imei_000000000000000.txt");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(60000);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String str;
while ((str = in.readLine()) != null)
{
urls.add(str);
}
in.close();
} catch (Exception e){
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
li = urls.get(0);
if (li.equals("track") || li.equals("find_mobile")) {
try{
URL url = new URL("http://192.168.43.164/add.php?long_itude=22.00023&lat_itude=22.00023");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(60000);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String str;
while ((str = in.readLine()) != null)
{
urls.add(str);
}
in.close();
} catch (Exception e){
e.printStackTrace();
}
Toast.makeText(getBaseContext(), "hello", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getBaseContext(), "not found"+ li, Toast.LENGTH_SHORT).show();
}
}
} );
}
}).start();
}
},5,5, TimeUnit.SECONDS);
posted code will work fine, but it's code working only in activity.
I want make that code background and run continuous without close.
use new thread = (Thread) function

Check for Active internet connection Android

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);
}

Categories