I am using this code, but it catches an error in a try-catch. Where is a mistake?
When I print a error, content.setText(ex.getMessage()); is empty.
Here is the relevant code:
public class MainActivity extends Activity {
TextView content;
EditText fname, email;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
content = (TextView) findViewById(R.id.content);
Button saveme = (Button) findViewById(R.id.save);
saveme.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Toast.makeText(getBaseContext(), "Please wait, connecting to server.", Toast.LENGTH_LONG).show();
try {
String loginValue = URLEncoder.encode("ffa", "UTF-8");
String fnameValue = URLEncoder.encode("fdsfdb", "UTF-8");
HttpClient Client = new DefaultHttpClient();
String URL = "http://mysite/app.php?a=" + loginValue + "&b=" + fnameValue;
try {
String SetServerString;
HttpGet httpget = new HttpGet(URL);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
SetServerString = Client.execute(httpget, responseHandler);
content.setText(SetServerString);
} catch (Exception ex) {
content.setText(ex.getMessage());
}
} catch (UnsupportedEncodingException ex) {
content.setText(ex.getMessage());
}
}
});
}
}
I think you get NetworkOnMainThreadException. You should perform network communication on background thread. Consider using IntentService or AsyncTask.
I have same opinion with Nickolai.
Work around:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Use code above, only when you are writing code for yourself.
If your application are produced to others,you need a better way.
Better way:
You should use a handle to access http-request, more info in developer.android.com
I use this myself:
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
String responseString = out.toString();
Related
BackgorundTask.java (How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?)
public class BackgroundTask extends AsyncTask<String,Void,String> {
public interface AsyncResponse {
void processFinish(String output);
}
public AsyncResponse delegate = null;
public BackgorundTask(AsyncResponse delegate){
this.delegate = delegate;
}
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
responseString = out.toString();
out.close();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
protected void onProgressUpdate(Integer... progress) {
}
#Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
}
ListActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
BackgorundTask asyncTask = (BackgorundTask) new BackgorundTask(new BackgorundTask.AsyncResponse(){
#Override
public void processFinish(String output){
listAdapter.add(output);
}
}).execute("some url");
adapter = new MyCustomAdapter(listAdapter, this);
final ListView mainListView = (ListView)findViewById(R.id.listView);
mainListView.setAdapter(adapter);
The variable is returned correctly. But I can not add to the ListView (listAdapter) of each item. What could be the reason? I suppose that I have to somehow pull the string variable output from asyncTask to my function onCreate in which it is placed.
your code is fine. you just need to call this line after adding data
listAdapter.add(output); // after this line add below line
listAdapter.notifyDataSetChanged();
The code to get the data back to the activity and to your listadapter seems okay to me. I think you just need to add a listAdapter.notifyDataSetChanged(); after listAdapter.add(output); so the listview knows it has to render itself anew.
You have to set the adapter again when you receive output string as below :
BackgorundTask asyncTask = (BackgorundTask) new BackgorundTask(new BackgorundTask.AsyncResponse(){
#Override
public void processFinish(String output){
listAdapter.add(output);
adapter = new MyCustomAdapter(listAdapter, this);
final ListView mainListView = (ListView)findViewById(R.id.listView);
mainListView.setAdapter(adapter);
}
}).execute("some url");
I have some problem with my HTTP Client project, with HTTP Method GET, The problem is, when i run my app on Android Emulator it works perfect, when i use my code in Java Desktop app, it works too, but when i import in APK file and load on my Android device, i does not works at all, I don't know why.
Class with Get Method:
public class httpGetExClass {
public String getInternetData() throws Exception {
BufferedReader in = null;
String data = null;
try {
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://yumecms.com/absolvent/public/");
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();
}
}
}
}
}
This is the MainActivity
public class MainActivity extends Activity implements OnClickListener {
TextView tv1;#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.textView1);
}
#Override
public void onClick(View arg0) {
httpGetExClass httpGet = new httpGetExClass();
httpPostExClass httPost = new httpPostExClass();
switch (arg0.getId()) {
case R.id.buttonEnter:
try {
Toast.makeText(this, "!!!!", Toast.LENGTH_SHORT).show();
String returned = httpGet.getInternetData();
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
tv1.setText(returned);
} catch (Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
break;
}
}
}
Your code is blocking and it's not allowed in Android. You must use another thread for your httpclient or use android specific AsyncTask.
i have this application force close with this code, what i do wrong?
public void buscaAno(View v){
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://sapires.netne.net/teste.php?formato=json&idade=55");
try {
HttpResponse response = httpclient.execute(httppost);
final String str = EntityUtils.toString(response.getEntity());
TextView tv = (TextView) findViewById(R.id.idade);
tv.setText(str);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It seems like this is onClick listener and it does a blocking operation on main thread which in turn causes ANR or NetworkOnMainThreadException. You should probably use AsyncTask or Service for your purpose.
For example, you could extend AsyncTask the following way:
private class PostRequestTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... strings) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(strings[0]);
try {
HttpResponse response = httpclient.execute(httppost);
return EntityUtils.toString(response.getEntity());
} catch (IOException e) {
//Handle exception here
}
}
protected void onPostExecute(String result) {
TextView textView = (TextView) findViewById(R.id.idade);
textView.setText(result);
}
}
And then use it like this:
public void buscaAno(View v) {
new PostRequestTask().execute("http://sapires.netne.net/teste.php?formato=json&idade=55");
}
I'm having a hard time to connect the application to the internet and retrieve the html source.
Been looking all over for a solution and didn't find. Hope someone could help.
Here is my code:
public class Main extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText et = (EditText) findViewById(R.id.editText1);
final Button b = (Button) findViewById(R.id.button1);
final TextView tv = (TextView) findViewById(R.id.textView1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
URL url=null;
url = new URL(et.getText().toString());
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
tv.append(line);
}
} catch (Exception e) {
}
}
});
}
I've also added INTERNET permission..
You need to move the code which connects to the internet and fetches data to an AsyncTask. This is because of the NetworkOnMainThreadException. This exception is thrown when an application attempts to perform a networking operation on its main thread.
Though there is a workaround available by using the StrictMode.ThreadPolicy, it highly advisable not to do that.
Here is a excerpt from the docs.
NetworkOnMainThreadException:-
This is only thrown for applications
targeting the Honeycomb SDK or higher. Applications targeting earlier
SDK versions are allowed to do networking on their main event loop
threads, but it's heavily discouraged.
See this question for more info.
Because you are doing this on UI therad.
Try this:
public class Main extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText et = (EditText) findViewById(R.id.editText1);
final Button b = (Button) findViewById(R.id.button1);
final TextView tv = (TextView) findViewById(R.id.textView1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Thread th = new Thread() {
#Override
public void run() {
try {
URL url=null;
url = new URL(et.getText().toString());
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
tv.append(line);
}
} catch (Exception e) {
}
}
};
th.start();
}
});
}
i will suggest you to use AsyncTask
Do this
On ButtonClick
RequestClient reqClient = new RequestClient(ActivityName.this);
String AppResponse = null;
AppResponse = reqClient.execute().get();
RequestClient
public class RequestClient extends AsyncTask<String, Void, String> {
Context context;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
try {
HttpClient httpclient = new DefaultHttpClient(); // Create HTTP Client
HttpGet httpget = new HttpGet("http://yoururl.com"); // Set the action you want to do
HttpResponse response = httpclient.execute(httpget); // Executeit
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent(); // Create an InputStream with the response
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) // Read line by line
sb.append(line + "\n");
String resString = sb.toString(); // Result is here
is.close(); // Close the stream
} catch (Exception e) {
Log.d("ANDRO_ASYNC_ERROR", "Error is " + e.toString());
}
Log.d("ANDRO_ASYNC_RESPONSE", responseString.trim());
client.getConnectionManager().shutdown();
return responseString.trim();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
Here is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"http://shopstable.turkcell.com.tr/timmenu/getPerosConfig.do");
try {
HttpResponse response = httpclient
.execute(httppost);
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}
});
}
});
}
i'am getting NetworkOnMainThreadException. I think the problem is in the httppost, but i couldn't figure it out.
This exception is thrown when an application attempts to perform a networking operation on its main thread.This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. Run your code in AsyncTask:
// use async task like this .this will solve ur problem
Class A{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
new RequestLogInFromServer().execute();
}
});
}
});
}
public class RequestLogInFromServer extends AsyncTask<Object, Object, Object>
{
#Override
protected Object doInBackground(Object... params)
{
String responsearray[] = new String[2];
//JSONObject jsonResponse = null;
// Create a new HttpClient and Post Header
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://shopstable.turkcell.com.tr/timme/getPerosConfig.do");
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
try {
// Add your data
in case if u want to pass any data to server else leave it
List<NameValuePair> signinDetails = new ArrayList<NameValuePair>();
signinDetails.add(new BasicNameValuePair("name",uname));
signinDetails.add(new BasicNameValuePair("pass",pwd));
httpPost.setEntity(new UrlEncodedFormEntity(signinDetails));
// Execute HTTP Post Request
HttpResponse httpResponse = httpClient.execute(httpPost);
Log.v("Post Status", "Code: "
+ httpResponse.getStatusLine().getStatusCode());
responseCode = httpResponse.getStatusLine().getStatusCode();
Log.e("responseBody", String.valueOf(responseCode));
responsearray[0]=String.valueOf(responseCode);
switch(responseCode){
case 200:
Log.e("responseCode", String.valueOf(responseCode));
HttpEntity entity = httpResponse.getEntity();
Log.e("entity", String.valueOf(entity));
if (entity != null) {
responsearray[1] = EntityUtils.toString(entity);
Log.e("responsearray", String.valueOf(responsearray));
/* Log.e("responseBody", String.valueOf(responseBody));
JSONTokener jsonTokener = new JSONTokener(responseBody);
jsonResponse = new JSONObject(jsonTokener);
Log.e("finalResult", String.valueOf(jsonResponse));
JSONObject response = jsonResponse.getJSONObject("response");
// Getting String inside response object
String status = response.getString("status");
String message = response.getString("message");
Log.e("status", String.valueOf(status));
Log.e("message", String.valueOf(message));
*/
} // if (entity != null) end
break;
case 503:
responsearray[1]="";
break;
default:
responsearray[1]="";
break;
}//switch end
} catch (ClientProtocolException cpeExp) {
// TODO Auto-generated catch block
} catch (Exception allExp) {
// TODO Auto-generated catch block
}
return responsearray;
}
#Override
protected void onPostExecute(Object result)
{
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(SignInActivity.this, "", "Please wait");
super.onPreExecute();
}
}
} //close class A
you have simply use this so get solution:
Here SDK version is your app's minimum sdk version ..so you have to set your minimum sdk version here. And put this code after onCreate() method:
if (android.os.Build.VERSION.SDK_INT > 8) {
StrictMode.ThreadPolicy stp = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(stp);
}
And also add this permission to your manifest file:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />