I'm writing my first Android app where the first thing to do is collect a list of maps from a server, but I'm having difficulty getting a simple REST request working. I've been following a number of tutorials and am trying to employ both AsyncTask and HttpURLConnection to do this properly.
For my simple initial test, I just call getMapsJson, with serverUrl set to "http://httpbin.org/ip" (just to make sure it's sending and receiving data correctly).
Code
public String getMapsJson()
{
Log.d(Globals.tag, ">> getting maps json from " + serverUrl.toString());
String output = "";
new GetMapsJsonTask().execute(serverUrl);
return output;
}
private class GetMapsJsonTask extends AsyncTask<URL, Void, String>
{
private HttpURLConnection connection = null;
protected String doInBackground(URL... url)
{
String output = "";
try
{
connection = (HttpURLConnection) url[0].openConnection();
connection.setRequestMethod("GET");
Log.d(Globals.tag, "connection opened!");
InputStream in = new BufferedInputStream(connection.getInputStream());
Log.d(Globals.tag, "input stream captured");
output = readStream(in);
Log.d(Globals.tag, "stream read");
}
catch (IOException e)
{
Log.d(Globals.tag, (e.getMessage() == null ? "IO Exception" : "IO : " + e.getMessage()));
}
finally
{
return output;
}
}
protected void onPostExecute(String json)
{
Log.d(Globals.tag, "Json response: " + json);
}
}
private String readStream(InputStream in) throws IOException
{
Log.d(Globals.tag, "entering readStream");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = reader.readLine();
String output = line;
while((line = reader.readLine()) != null)
output += line;
return output;
}
AndroidManifest.xml
I have the android.permission.INTERNET line in there, but I'm not positive it's in the correct location. May cause issues?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.northstar.minimap"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name="com.northstar.minimap.Globals"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.northstar.minimap.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.northstar.minimap.MapActivity"
android:label="#string/title_activity_map"
android:parentActivityName="com.northstar.minimap.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.northstar.minimap.MainActivity" />
</activity>
</application>
</manifest>
Output
Logcat yields the following lines:
12-01 21:31:44.727 2188-2188/com.northstar.minimap D/Minimap﹕ >> getting maps json from http://httpbin.org/ip/
12-01 21:31:44.727 2188-2232/com.northstar.minimap D/Minimap﹕ connection opened!
12-01 21:31:45.106 2188-2232/com.northstar.minimap D/Minimap﹕ IO: http://httpbin.org/ip/
12-01 21:31:45.106 2188-2188/com.northstar.minimap D/Minimap﹕ Json response:
Basically, something's causing an IOException, and I'm not sure what - the exception's getMessage isn't exactly verbose. Do I have to do any configuration for the emulator (JellyBean, API level 17)?
Thanks!
Related
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
Recently i am developing Android applications
what i wanted to do is consume a web services
from .net WCF into my application
Here is my Client Code
import java.io.InputStream;<br>
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;<br>
import org.apache.http.HttpResponse;<br>
import org.apache.http.client.methods.HttpGet;<br>
import org.apache.http.impl.client.DefaultHttpClient;<br>
import org.json.JSONObject;<br>
import android.R.string;<br>
import android.os.Bundle;<br>
import android.app.Activity;<br>
import android.view.Menu;<br>
import android.view.View;<br>
import android.widget.TextView;<br>
public class MyPamIndex extends Activity {
private final static String SERVICE_URI = "http://172.30.2.95:9000/JSON/MyPam.svc";
private TextView NabVals;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_pam_index);
NabVals = (TextView)findViewById(R.id.textView2);
}
public void OnRefreshClick(View button)
{
try {
// Send GET request to <service>/GetVehicle/<plate>
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(SERVICE_URI + "/ProductID/" + "1");
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// Read response data into buffer
char[] buffer = new char[(int)responseEntity.getContentLength()];
InputStream stream = responseEntity.getContent();
InputStreamReader reader = new InputStreamReader(stream);
reader.read(buffer);
stream.close();
JSONObject vehicle = new JSONObject(new String(buffer));
NabVals.setText(vehicle.getString("NabValue"));
// Populate text fields
} catch (Exception e) {
e.printStackTrace();
}
}
when i run the apps it have an error
in
HttpResponse response = httpClient.execute(request);
i have search the entire forum but found nothing
i already add my android manifest file but still does not working
please help me
this is my Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.core.mypam"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="anroid.permission.INTERNET"></uses-permission>
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="16" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.core.mypam.MyPamIndex"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
"http://172.30.2.95:9000" is not my machine IP but its located on other PC within same LAN
Please help me
You're making a network request on the UI thread. That is no longer allowed and, and will raise an exception. You need to move your code into an AsyncTask. Google NetworkOnMain for a plethora of examples.
I've seen similar posts about this problem, but none of them relate to the use of the Visual Studio development server for ASP .NET.
I'm receiving the following error.
An established connection was aborted by the software in your host machine.
And I'm executing the following code:
String employeesJson = client.downloadString("http://localhost:60000/Api/Employee/GetEmployees.aspx");
When I run this in a regular webbrowser (Chrome 21 or Internet Explorer 10) it runs just fine. I get the JSON result that I want.
And my WebClient class being used (under the variable "client") is defined as follows.
public class WebClient {
private HttpClient httpClient;
public WebClient() {
httpClient = new DefaultHttpClient();
}
public String downloadString(String url) throws IOException {
HttpGet get = new HttpGet(url);
try {
HttpResponse response = httpClient.execute(get); //this is where the error occurs.
HttpEntity entity = response.getEntity();
if(entity != null) {
InputStream stream = entity.getContent();
InputStreamReader streamReader = new InputStreamReader(stream);
BufferedReader bufferedReader = new BufferedReader(streamReader);
StringBuilder builder = new StringBuilder();
String line = null;
try {
while ((line = bufferedReader.readLine()) != null) {
builder.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return builder.toString();
}
//catch all the types of exceptions this method can throw. catching "Exception" is considered bad.
} catch (ClientProtocolException e) {
e.printStackTrace();
}
return null;
}
}
My AndroidManifest.xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="specialisering.android"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
face same problem, it was firewall stoping it .... so turned off the firewall and it working now... :)
I can't believe I didn't seek an answer from the documentation. It clearly states that 127.0.0.1 is the IP of the emulator itself, while 10.0.2.2 is the IP of the developer machine.
Changing from localhost to 10.0.2.2 solved my issue.
I'm trying to get the HTML source in a string from a web site that the user enters, the code I have so far looks like this:
public String getURLContent(String url)
{
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
ResponseHandler<String> resHandler = new BasicResponseHandler();
String page = httpClient.execute(httpGet, resHandler);
return page;
}
catch (ClientProtocolException e)
{
e.printStackTrace();
return "";
}
catch (IOException e)
{
e.printStackTrace();
return "";
}
}
Every time I try to run this I hit the second catch (IOException), which according to the documentation means the server failed to give a valid response... I am testing this with sites like "http:\www.google.com\", so they should definitely be responding
Your code is ok. Make sure you paste full website path : http://www. [page] . [domain] eg.: http://www.google.com
And add this PERMISSION to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
just before (if it is new project):
<application android:label="#string/app_name">
Full example:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10"/>
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="#string/app_name">
<activity android:name="MyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Unless you want to do some custom parsing with the whole string, I would advise you to use an HTML parser lib. I use HTML cleaner, showed here.
That makes all the horse work for you.
hi I am trying to fetch data from link as given below
http://abovestress.com/app_stress/fetch_all_detail.php?task=fetchtimefromdateanduserid&track_date=2011-08-09&tracker_user_id=374
but I can't get result my code is here
package com.JsonDemo;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class JsonDemoActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<String> fetchsosfromID = new ArrayList<String>();
String result = "";
InputStream is = null;
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("track_date","2011-08-09"));
nameValuePairs.add(new BasicNameValuePair("tracker_user_id",""+374));
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"http://abovestress.com/app_stress/fetch_all_detail.php?task=fetchtimefromdateanduserid&");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
// convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Log.v("log_tag", "Append String " + result);
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
// parse json data
try {
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
fetchsosfromID.add(json_data.getString("track_time"));
Log.v("log_tag", "daily_data " + fetchsosfromID);
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
}
}
and error comes like this
08-09 17:29:01.315: ERROR/log_tag(2291): Error in http connection java.net.UnknownHostException: abovestress.com
08-09 17:29:01.315: ERROR/log_tag(2291): Error converting result java.lang.NullPointerException
08-09 17:29:01.345: ERROR/log_tag(2291): Error parsing data org.json.JSONException: End of input at character 0 of
manifiest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.JsonDemo"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".JsonDemoActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-permission android:name="android.permission.INTERNET"/>
</application>
</manifest>
You've definitely added the
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
in your manifest, right?
Edit: Your <uses-permission> is in the wrong place. It should look like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.JsonDemo"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".JsonDemoActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
you need to put permission tag put of application tag...
The exception you get points to a name resolution problem (getting abovestress.com ip address from DNS server). That is probably because your network is down.
A simple snippet to check if a network connection is up, where Context ctx is you Activity context:
public boolean checkConnection(Context ctx) {
ConnectivityManager conMgr =
(ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo i = conMgr.getActiveNetworkInfo();
if (i == null)
return false;
if (!i.isConnected())
return false;
if (!i.isAvailable())
return false;
return true;
}
EDIT:
if network in not your problem, have a look here and here
you may need to add (besides android.permission.INTERNET) other permissions:
android.permission.ACCESS_NETWORK_STATE
android.permission.READ_PHONE_STATE
and/or:
try {
InetAddress i = InetAddress.getByName(URLName);
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
// ... actually using URL
EDIT 2: AND, as noted by others, uses-permission element goes inside manifest element, not application element