I use the following class to retrieve data from a website:
public class GetMethodEx {
public String getInternetData() throws Exception {
BufferedReader in = null;
String data = null;
try {
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.google.com");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) != null) {
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
} finally {
if (in != null) {
try {
in.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
And the following class uses the above class to print the retrieved data on the screen:
public class HttpExample extends Activity {
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.httpex);
httpStuff = (TextView) findViewById(R.id.tvHttp);
GetMethodEx test = new GetMethodEx();
String returnedData = null;
try {
returnedData = test.getInternetData();
httpStuff.setText(returnedData);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have set the "httpStuff" TextView to "loading..." in the "httpex" xml. Now the problem I am facing is that when I run the app, it is stuck at this "loading..." forever. Any ideas why?
Thanks.
PS: I have added the permission "android.permission.INTERNET" in the manifest.
EDIT: Actually I have a duplicate question which has the correct solution. Anyway, thanks!
Make sure to check LogCat to look for potential error messages. I'm guessing you didn't request the Internet permission in your AndroidManifest.xml.
Add
<uses-permission android:name="android.permission.INTERNET" />
outside the application tag in your AndroidManifest.xml
Edit:
Also, you should avoid running network requests on the UI thread. On later versions of android (Honeycombe and later I believe) you'll get a NetworkOnMainThreadException, which could also cause the issue you're facing.
Try using an AsyncTask to run this request. See the answer here:
How to fix android.os.NetworkOnMainThreadException?
Related
I'm learning android by working on a simple project. I have the layout completed and I'm at a point where I need to communicate with the back-end. I've worked with PHP/JSON a lot before and I know exactly what I need to do on the back-end. I have the following two questions,
1 - What kind of adapter I should be using when dealing with JSON? please note that the back-end will be sending 10 records at a time, and the user will scroll up to get the next 10 so the dataset will be changing as the user scrolls the view
2 - I'll be using HTTP to get the JSON data mentioned in point 1, is there a preferred method in android to be used for communication with the back-end?
Please note that I don't want to Parse or any other cloud solutions.
1. You will have to have a something which will communicate with the server for that just copy this code :-
public class ConnectionClass
{
Context context;
public ConnectionClass(Context ctx) {
this.context=ctx;
}
public String connectToServer(String urlLink)
{
try
{
HttpClient client = new DefaultHttpClient();
HttpPost http_get = new HttpPost(urlLink);
HttpResponse responses;
responses = client.execute(http_get);
if (responses != null)
{
InputStream in = responses.getEntity().getContent();
String a = convertStreamToString(in);
return a;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try
{
while ((line = reader.readLine()) != null)
{
sb.append(line);
}
}
catch (Exception e)
{
//Toast.makeText(context, e.toString()+" io2", Toast.LENGTH_LONG).show();
}
finally
{
try
{
is.close();
}
catch (Exception e)
{
}
}
return sb.toString();
}
}
2. To use that and keeping in mind dat newer version of android does not allow executing network operations on mainthread i will give a simple example to run on onCreate() of the activity using AsyncTask this is something like Ajax in web .
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
context=this;
ConnectionClass cc=new ConnectionClass(context);
new AsyncTask<String, Void, String>()
{
#Override
protected String doInBackground(String... arg) {
String data=cc.connectToServer(arg[0]);
return data;
}
protected void onPostExecute(String result)
{
super.onPostExecute(result);
try
{
JSONObject jobj=new JSONObject(result);
String idval=jobj.getString("id");
Toast.makeToast(context,idval,2000).show();
} catch (Exception e)
{
e.printStackTrace();
}
}
}.execute("http://mydomain.com/fetchjson.php");
}
Android has built-in JSON parsing capability and an Http client. Take a look at this stackoverflow post, which has step-by-step instructions for making the Http request and parsing the returned JSON data:
How to parse JSON in Android
However, this post uses the older DefaultHttpClient. This is only recommended for Froyo and below. For newer code, Google recommends that you use HttpURLConnection instead (on Gingerbread and higher API systems). Their function is very similar, here is the reference for Android's HttpURLConnection:
HttpURLConnection | Android Developers
I wrote a simple method to get some string data using the apache HTTPClient, however it returns a blank screen when I run it on my phone; I'm trying to display the data in a textarea. The manifest has the internet permission. Can anybody point out what I could be doing wrong?
public String getInternetData() throws Exception
{
BufferedReader in = null;
String data = null;
try
{
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.yahoo.com");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while((l=in.readLine())!=null){
sb.append(l+nl);
}
in.close();
data = sb.toString();
return data;
}finally{
if(in !=null){
try{
in.close();
return data;
}catch (Exception e){
e.printStackTrace();
}
}
}
}
for completeness, I am adding the code I use to see the data.
public class MainActivity extends Activity {
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
httpStuff = (TextView) findViewById(R.id.tvHttp);
GetMethodEx test = new GetMethodEx();
String returned;
try {
returned = test.getInternetData();
httpStuff.setText(returned);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You are probably getting Network on UI thread error, and because it is in a try catch, the app isnt crashing
you are supposed to invoke network operations only in background threads, or AsyncTasks which are great for that
there is nothing wrong with your HTTP client and request data, the problem indeed lies in your onCreate method
try rewriting it this way
public class MainActivity extends Activity {
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
httpStuff = (TextView) findViewById(R.id.tvHttp);
AsyncTask<Void,Void,String>getDataTask = new AsyncTask<Void,Void,String>(){
#Override
protected String doInBackground(Void... params){
GetMethodEx test = new GetMethodEx();
String returned = test.getInternalData();
return returned;
}
#Override
protected void onPostExecute(String returned){
httpStuff.setText(returned);
}
}
}
getDataTask.execute();
}
This question already has answers here:
AsyncTask Android example
(21 answers)
Closed 9 years ago.
Im making an android program that parses JSON texts from a source code of a webpage in the internet. It is working in android 2.2 but I need it now to be on android 3.0, which needs to be on the AsyncTask. I have a background about AsyncTask but I'm so confused where to put this and that. Thanks in advance everyone :)
Here is my method in the MainActivity class:
private void jsonStuffs() {
//JSON PARSER & HOME PAGE TEXTVIEWS
client = new DefaultHttpClient();
GetMethodEx test = new GetMethodEx();
String returned;
try {
returned = test.getInternetData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try{
String jsonStr = test.getInternetData(); //go to GetMethodEx
JSONObject obj = new JSONObject(jsonStr);
//////////////////////find temperature in the JSON in the webpage
String temperature = obj.getString("temperature");
TextView tvTemp = (TextView)findViewById(R.id.textView);
tvTemp.setText(temperature);
}
//catch (JSONException e) {
// e.printStackTrace();
//}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The GetMethodEx class is this (this will find the link of the webpage then convert it's source code to text format):
public class GetMethodEx extends Activity {
public String getInternetData() throws Exception{
BufferedReader in = null;
String data = null;
//
try{
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://nhjkv.comuf.com/json_only.php");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) !=null){
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
}finally {
if (in !=null){
try{
in.close();
return data;
} catch (Exception e){
e.printStackTrace();
}
}
}
}
}
You can do something like this (this code is just for illustration, change it as needed)
class MyAsyncTask extends AsyncTask<String, Void, JSONObject> {
protected void onPreExecute() {
// You can set your activity to show busy indicator
//setProgressBarIndeterminateVisibility(true);
}
protected JSONObject doInBackground(String... args) {
return jsonStuffs();
}
protected void onPostExecute(final JSONObject jsonObj) {
String temperature = jsonObj.getString("temperature");
TextView tvTemp = (TextView)findViewById(R.id.textView);
tvTemp.setText(temperature);
// Stop busy indicator
//setProgressBarIndeterminateVisibility(false);
}
To call this task use new MyAsyncTask().execute(); (you can pass String parameters to execute if needed)
You can change your jsonStuffs() to return JSONObject
e.g.
private JSONObject jsonStuffs() {
// ...
String jsonStr = test.getInternetData(); //go to GetMethodEx
return new JSONObject(jsonStr);
// ...
}
It is working in android 2.2 but I need it now to be on android 3.0,
which needs to be on the AsyncTask.
=> Yes it gives NetworkOnMainThreadException in 3.0 if you make web call without implementing inside Thread such as AsyncTask.
I have a background about AsyncTask but I'm so confused where to put
this and that.
=> Simply include web call logic inside doInBackground() method of the AsyncTask, in your case call getInternetData() inside doInBackground().
FYI, you can't update UI straight way while doing long running task inside the doInBackground(). Yes if you want to update UI then do follow any of the below:
Update UI from the onPostExecute() method.
or implement runOnUiThread() inside the doInBackround()
I require a GET reequest from my own server to be extracted from the web and then displayed on screen with a TextView.
I have set up a GET Request.
public class GetMethodEx {
public String getInternetData() throws Exception{
BufferedReader in = null;
String data = null;
try
{
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.mybringback.com");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) !=null){
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
} finally{
if (in != null){
try{
in.close();
return data;
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
And I have set up on my main thread to extract the information and display it in a text view.
public class Home extends Activity {
TextView httpStuff;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.httpexample);
httpStuff = (TextView) findViewById(R.id.tvhttp);
GetMethodEx test = new GetMethodEx();
String returned;
try {
returned = test.getInternetData();
httpStuff.setText(returned);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
However, the Textview doesnt seem to change?
Can someone help me please.
Change your code using AsyncTask if you want to make any network operation from Ui Thread as:
public class Home extends Activity {
TextView httpStuff;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.httpexample);
httpStuff = (TextView) findViewById(R.id.tvhttp);
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
GetMethodEx test = new GetMethodEx();
String returned;
try {
returned = test.getInternetData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return returned;
}
#Override
protected void onPostExecute(String result) {
// Update Ui here
httpStuff.setText(result);
}
}
}
Android OS > = 3.0
does not allow NetworkRequest on main UI thread.
Use AsyncTask to call webrequest.
im pretty new In Android App development, I need some help.
Im creating this simple dictionary application that prompts the user to enter a word and after a button press it will take that word to the internet, probably wikipedia.org and return that information to the User.
I used XML to develop the app textfield and button. And created a piece of text (ansa) which will be set to whatever the answer is using the OnClickListener,
I do not want to set up a webview
I just want the text to be set to the dictionary answer.
Here's what i have been able to do so far. There is this class to get data from google.
public class GetMethod {
public String getInternetData() throws Exception{
BufferedReader in = null;
String data = null;
try{
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.google.com");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while((l = in.readLine()) !=null){
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
}finally{
if (in !=null){
try{
in.close();
return data;
}catch(Exception e){
e.printStackTrace();
}
}
}
}
And Another class where the XML is implemented
public class Dictionary extends Activity {
TextView ansa;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dictionary);
Button Search = (Button) findViewById(R.id.search);
ansa = (TextView) findViewById(R.id.ansa);
final GetMethod test = new GetMethod();
Search.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String returned;
try {
returned = test.getInternetData();
ansa.setText(returned);
} catch (Exception e) {
ansa.setText("Failed");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
When it executes I get the whole website's HTML
So I need help on how to take the user's word to the wiki website, and get only the text of the ansa, probably parse and store it to some string.
Thank You Alot.
You can use an API like Google Dictionary or dictionary.com.
But you will have to implement the HTTP client and parse the response. And then show the desired data .