Android app hangs on HttpUrlConnection request - android

I created a small demo program
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(new Requester()).execute();
}
static class Requester extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... voids) {
URL loginURL;
HttpURLConnection urlConnection;
try {
loginURL = new URL("https://google.com");
urlConnection = (HttpURLConnection) loginURL.openConnection();
int responseCode = urlConnection.getResponseCode();
Log.d("response", "response is" + responseCode);
}
catch (MalformedURLException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
return null;
}
}
}
I set a breakpoint at int responseCode = urlConnection.getResponseCode(); and then step through. It never gets to the next line for me to read the response code. There is no error; it just hangs forever.
I feel like this is the most basic urlconnection code I can come up with. Perhaps I'm missing something important.
Edit: I have indeed added the internet permission to my manifest. Here is my entire manifest just in case you want it:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testingcorruptbitmap">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Update:
I've edited my code to include reading from the request.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(new Requester()).execute();
}
static class Requester extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... voids) {
URL loginURL;
HttpURLConnection urlConnection;
try {
loginURL = new URL("https://google.com");
urlConnection = (HttpURLConnection) loginURL.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = reader.readLine();
Log.d("urlconnection", "line is " + line);
int responseCode = urlConnection.getResponseCode();
Log.d("urlconnection", "response is " + responseCode);
}
catch (MalformedURLException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
catch (Exception e){
e.printStackTrace();
}
return null;
}
}
}
When I set a breakpoint at the beginning of the code and walkthrough, it freezes at InputStream in = new BufferedInputStream(urlConnection.getInputStream());
So this does not solve the issue.
Solution update:
Something was wrong with the android emulated device I was working on. I restarted it and the problem is now fixed. If you know of the reason why this would happen please let me and the rest of the internet know, so we can avoid it!

You are not doing an actual request, so there is no response either, that's why your code is waiting for a response.
See here: Http Get using Android HttpURLConnection

have you added the INTERNET permission in your AndroidManifest? If not do so.
If you did take a look at this document by android-dev. It shows how to make simple requests using the volley library.
Hope this helps
Edit:
I personally never worked with URLConnection but according to the android docs you have to do it like this:
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
} finally {
urlConnection.disconnect();
}
Source: https://developer.android.com/reference/java/net/HttpURLConnection
In your example you just created a HttpURLConnection but never executed it and thats why you can'T get something of it.
While it can definitly work this this method I would greatly encurage you to take a look at Volley as it is more simple and easier to use. It also helps you with JSONRequests. Furthermore it is async by default meaning you don't need to use the deprecated AsyncTask anymore.
Edit 2:
When trying to connect to a secure website over https as you try to do in your example you need to cast to HttpsURLConnection instead.

I also have the same problem, the call to the getResponseCode method freezes. If I set a timeout, the timeout expired exception is thrown.
But all of the above happens when I have the phone in power saving mode, if I remove it, the call to the getResponseCode method works perfectly.
If the Volley api is used, a timeout also occurs.
But this only happens in background processes for example when updating a widget due to restrictions imposed by the system.
The solution is to add your app to the list of energy saving exclusions. Although this can be done through the PowerManager api, it is preferable that it be the user of your app who does it, as discussed in this answer https://stackoverflow.com/a/53115804/1735246.

Related

Getting JSON data from a PHP server

I am trying to get json data from a table that i am querying in my wamp server with a select.php the data shows in the browser but android for some reason can't download the data.
select.php
<?php
$conn=mysqli_connect("localhost","root","", "shady") or die("Unable to connect");
if(mysqli_connect_error($conn)) {
echo "Failed To Connect";
}
$qry = "SELECT * FROM `wellden`";
$res = mysqli_query($conn, $qry);
if ($res) {
while ($row = mysqli_fetch_array($res)) {
$flag[] = $row;
}
// returns tthe json data
echo json_encode($flag);
}
mysqli_close($conn);
?>
works fine and prints data in browser:
but for some weird reason android cant seem to get the echoed data from the php file.
Android code:
public class ListOfCourses extends AppCompatActivity {
ListView listView;
ArrayList<String> arrayList;
ArrayAdapter<String> arrayAdapter;
String REG_URL;
public class Listdata extends AsyncTask<String, Void, String>{
HttpURLConnection conn;
URL url;
String jsonStringForMe;
#Override
protected String doInBackground(String... strings) {
// MOST CRITICAL PART.....................................
String s = strings[0];
try {
url = new URL(s);
conn = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while ((line = reader.readLine()) != null) {
// Append server response in string
sb.append(line);
}
// Stroring it to use in the onPostExecute Cause we do not have any Button in this view
jsonStringForMe = sb.toString();
return jsonStringForMe;
}catch (Exception e){
return e.getMessage();
}
// MOST CRITICA PART ENDS HERE..............................
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// JsonParsing Happens Here
Toast.makeText(getApplicationContext(), jsonStringForMe+" ", Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_of_courses);
Listdata listdata = new Listdata();
REG_URL="http://1.0.0.2/android_db_pool/select.php";
listdata.execute(REG_URL);
}
}
but everytime the jsonStringForMe gives me null in postExecute everything seems Ok should work, but for some reason does not work. What can be the cause of the json data not receiving in the android end ?
EDIT
I added internet permission also:
AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.slimshady.jamalsir1">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ListOfCourses"></activity>
</application>
</manifest>
EDIT 2
It may seem that ip address may be an issue but it is not insertion works fine with insert.php, and i can get the json data with the ip address that is my server's ip address 1.0.0.2. In android i am using the ip address of the server not localhost in only php i am using localhost because the php file is in my server.
As already commented;
Stroring it to use in the onPostExecute Cause we do not have any
Button in this view
You didn't add or use to get the json in onPostExecute() method but you have added the Toast in onPreExecute.
Try to add onPostExecute() then show Toast.
protected void onPreExecute()
Runs on the UI thread before doInBackground(Params...).
https://developer.android.com/reference/android/os/AsyncTask#onPreExecute%28%29

How to implement a JSON handler/helper class to handle JSONrequest on Android Studio [duplicate]

This question already has an answer here:
Android AsyncTask example and explanation [duplicate]
(1 answer)
Closed 5 years ago.
I need to reach a JSON hosted somewhere on the web, retrieve it and manipulate it.
To do this, I know it's recommended to implement a handler class to help with the JSON calls and all but I cannot remember the how-to. I do remember you could do it extending AsyncTask and using String, Void and JSONObject as the wildcards, you know, like this:
public class JSONhandler extends AsyncTask <String, Void, JSONObject>{
//code here
}
I would like to do this strictly by extending AsyncTask<>. I'm aware this question addresses the use of AsyncTask but that's not how I'm looking for it. That question's code extends Activity, and I do not which this class to be an Android Activity, I wanna implement this class in an Android Activity.
The thing is I do not remember the how-to.
Thanks in advance.
There are many ways to do this, if you wanna use the AsyncTask the code inside your class should be the following
public class JSONrequest extends AsyncTask<String, Void, JSONObject> {
// First you'll need an interface that'll call requestDone() for the JSONobject you wanna listen
public interface JSONListener{
void requestDone(JSONObject jsonObject);
}
private JSONListener jListener;
//Your class will need a constructor. Basic Java.
public JSONrequest(JSONListener jListener){
this.jListener = jListener;
}
#Override
//You'll be required to implement this method because of the extension and
//here's where the logic of your handler class goes
protected JSONObject doInBackground(String... strings) {
// First try to retrieve the url
JSONObject result = null; //initializing the result we'll return
try{
URL url = new URL(strings[0]);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
int responseCode = urlConnection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
InputStream is = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String currentLine = "";
while((currentLine = br.readLine()) != null){
Log.d("JSON REQUEST", currentLine); //a little log so you can see what's going on
sb.append(currentLine);
}
result = new JSONObject(sb.toString());
}
}catch (Exception e){
e.printStackTrace();
}
return result;
return null;
}
}
If you're gonna fetch your JSON from a server it's very important that you give your app the permission to use Internet.
To do this, you add the following line to the Android Manifest:
<uses-permission android:name="android.permission.INTERNET" />
I hope this solves your problem.
Good luck.

Android App crashes but the code shows no error

Okay so I'm trying to make an app that is able to retrieve data from a web server and then show it on a textView and constantly update it if the data changes from the web server. And what I got so far after many rounds of trying is this as shown
public class HttpTest extends AppCompatActivity {
TextView text = (TextView) this.findViewById(R.id.textView3);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_http_test);
HttpURLConnection urlConnection = null;
try {
URL url = new URL("http://IPGOESHERE/");
HttpURLConnection urLConnection = (HttpURLConnection) url.openConnection();
InputStream in = urLConnection.getInputStream();
BufferedReader data = new BufferedReader(new InputStreamReader(in));
StringBuilder total = new StringBuilder();
String line;
while ((line = data.readLine()) != null) {
total.append(line).append('\n');
}
String result = total.toString();
text.setText(result);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
I don't think what i have written allows for constant update, but I at least want to be able to show some kind of data on a textView and make sure it doesn't crash first. So if someone could point out what I'm doing wrong it will be much appreciated.
The app crash because you are making HTTP request on main thread. Use an AsyncTask instead
you need to this kind of work on a different thread. try using an AsyncTask.
you create a class that extends AsyncTask, than make the url connection in the doInBackground method (a method that gets called on a worker thread). you can then update the textview in the onPostExecute method which is called on the ui thread. good luck :)

trying to access a url from android activity

I want to access a url in my android activity, for storing a string thats passed as a parameter on the url itself with a webservice that i have built. at this point, i just want to access the url and see that it happens, and later on i will worry about doing something with the result (what the request returns back). I'm using HttpURLConnection. I'm getting this error:
D/SntpClient( 59): request time failed: java.net.SocketException: Address fami
ly not supported by protocol
my code is:
public void storeScore()
{
Log.d("storeScore","is running");
HttpURLConnection con = null;
//DefaultHttpClient
try {
URL url = new URL("http://www.google.com");
con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(10000);
con.setConnectTimeout(15000);
con.setRequestMethod("GET");
con.setDoInput(true); //also tried without this
con.setDoOutput(true); //also tried without this
con.connect();
Log.d("storeScore","got to connect");
//not really reading the result at this point:
//BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
//String payload = reader.readLine();
//reader.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("MalformedURLException",e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("IOException",e.getMessage());
e.printStackTrace();
}
}
the app android manifest includes both premissions:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
this method storeScore() is ran from a thread that is created onCreate and started. Am i doing something wrong here? If you need more relevant information that i didn't add here, tell me and I will edit the question. Thanks, i appreciate any assistance.

Sometimes my app crashes with UnknownHostException

In my app i have access to web server. It works fine in Some phones but while testing in Samsung Galaxy
Model No - GT-S5830i
Android Version - 2.3.6
it keeps on showing Unknown host exception. I have checked the url from browser its working fine.
private void submitUploadData(String url ,Map<String, String> param) throws IOException
{
URL siteUrl;
try {
siteUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) siteUrl.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
Set getkey = param.keySet();
Iterator keyIter = getkey.iterator();
String content = "";
for(int i=0; keyIter.hasNext(); i++) {
Object key = keyIter.next();
if(i!=0) {
content += "&";
}
content += key + "=" + param.get(key);
}
out.writeBytes(content.trim());
out.flush();
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
while((line=in.readLine())!=null) {
System.out.println(line);
}
in.close();
//Intent home = new Intent(SyncHttp.this,TimeAndExpensesSKActivity.class);
//startActivity(home);
db.updateTimeExported(1);
db.updateExpensesExported(1);
db.close();
db.close();
if(db.getLogCount()==0){
db.insertSyncDateDetails(getDateandTime());}
else{
db.updateSyncDateDetails(1, getDateandTime());}
} catch (MalformedURLException e) {
e.printStackTrace();
}
this.setResult(FINISH_RESULT);
db.close();
}
I have already added permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
I am really confused why this exception occurring.
Thanks for your help guys.
My app did this too. This usually caused by unstable network connection. What I did was catching this UnknownHostException and modify the code in a way that if UnknownHostException happened, I try to re-fetch the URL again, after several miliseconds sleep.
The basic algorithm is something like this:
private void submitUploadData(String url ,Map<String, String> param) throws IOException
{
URL siteUrl;
boolean isDataSubmitted = false;
while(!isDataSubmitted){
try {
//do your complicated http process
isDataSubmitted = true;
} catch(UnknownHostException uhe){
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
I have also experienced some issues using URLConnections especially HTTPS on the Samsung Galaxy TAB, but i would imagine it probably occurs on other models as well since there are a ton of devices with the same name but made for different markets and mobile providers.
So far i haven't found a way around sorry, since i tend to avoid the URLConnection class due to a ton of other issues it has.
I suggest using the Apache HTTP Client to communicate with your API's. you can google a ton of examples of using it.
Also when looking at your code i would suggest reading a bit more into the try-catch-finally block statements in java. it is really important to properly close connections at the end or in case of errors.
Other possibilities are:
There is no connection of any sort active (mobile or wifi)
You are missing the "http://www." in your url.
I think calling close() on the DataOutputStream before you recieve your input might close the whole connection - try commenting out that line.
Have you checked the URL from the phone's browser?
Please log the URL you pass to the function and try it in your phone's browser. I would think of missing/incorrect protocol specifier and or URL string formation issues of which this particular phone is unforgiving.

Categories

Resources