The below code is from my MANIFEST.XML FILE
The below works : <receiver android:name="com.PageP.Alarm>
But, when i add the process it doesn't fire :
<receiver android:process=":remote" android:name="com.PageP.Alarm>
I have a break point at :
public void onReceive(Context context, Intent intent)
If no remote process, it works, if i add the remote process it stops working.
What am i missing???
OKAY, LET ME POST MY ASYNC HTTPGET
package com.PageP;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
public class GrabURL extends AsyncTask<String, Void, Void> {
private HttpClient Client = new DefaultHttpClient();
private String content;
private String Error = null;
private String url = null;
protected void onPreExecute() {
// Dialog.setMessage("Downloading source..");
// Dialog.show();
}
protected Void doInBackground(String... urls) {
url = urls[0];
try {
HttpGet httpget = new HttpGet(urls[0]);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
content = Client.execute(httpget, responseHandler);
} catch (ClientProtocolException e) {
Error = e.getMessage();
cancel(true);
} catch (IOException e) {
Error = e.getMessage();
cancel(true);
}
return null;
}
protected void onPostExecute(Void unused) {
Login.GotURL(content, url);
Client = null;
}
}
AND THEN I CALL IT WITH
public static void Ping(String Args) {
final GrabURL wget = new GrabURL();
String url = "";
url = MyAuth("PING")+ Args;
wget.execute(PPURL+url);
}
WHEN MY ALARM TRIGGERS, I WANT IT TOO STAY AWAKE TO RECEIVE THE DATA ON THE OTHER END WHERE I DECODE THE RETURNED HTML. I AM HAVING PROBLEMS WHERE WHEN THE ANDROID GOES INTO SLEEP MODE, IT ISN'T RELIABLY RECEIVING THE HTML RETURNED DATA.
What am i missing?
Since having a separate process is generally a bad idea, just leave android:process off.
I need it to stay AWAKE long enough call a async wget and process the returned html.
I do not know what you consider an "async wget" to mean. I am going to assume that you literally mean that you are packaging an ARM-compiled wget binary with your app, which is bizarre beyond words.
Moreover, Android will terminate your process within seconds, for tying up the main application thread of that process. So you will waste RAM, CPU, and battery for no particular advantage.
Use HttpUrlConnection or HttpClient to do your HTTP request ("async wget"), from a WakefulIntentService, or your own IntentService that handles the WakeLock issues surrounding the use of _WAKEUP alarms. IntentService gives you a background thread (necessary for doing long-running work) and will automatically shut down when it is no longer needed (necessary so users don't attack you with task killers for harming their devices).
i could go into a do/loop and sleep within it waking up every 250 milli seconds to see if the data has come in
If you use HttpUrlConnection or HttpClient to do your HTTP request, you will know "if the data has come in" by virtue of those APIs.
with a set time out
If you use HttpUrlConnection or HttpClient to do your HTTP request, you will be able to specify a request timeout period.
Related
I have this exception and I was reading a thread on this, and it seemed confusing:
How to fix android.os.NetworkOnMainThreadException?
I already added this line to my manifest:
<uses-permission android:name="android.permission.INTERNET" />
On that discussion, they talk about the main execution thread of the app not being able to do networking. What I am wondering is how to restructure my code so that it is inline with Android good practices.
Here is my Activity class for this:
package com.problemio;
import java.io.InputStream;
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 android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class LoginActivity extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
// Show form for login_email
final EditText loginEmail = (EditText) findViewById(R.id.login_email);
String name = loginEmail.getText().toString();
// Show field for password
final EditText password = (EditText) findViewById(R.id.password);
String text = password.getText().toString();
// Show button for submit
Button submit = (Button)findViewById(R.id.submit);
// Show options for create-profile and forgot-password
submit.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
String email = loginEmail.getText().toString();
String pass = password.getText().toString();
sendFeedback(pass, email);
}
});
}
public void sendFeedback(String pass , String email)
{
Log.d( "1" , pass );
Log.d( "1" , email );
// Go to db and check if these r legit
// How do I do that? :)
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("username", email ));
postParameters.add(new BasicNameValuePair("password", pass ));
String responseString = null;
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("myUrl");
// no idea what this does :)
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
// This is the line that send the request
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
}
catch (Exception e)
{
Log.e("log_tag", "Error in http connection "+e.toString());
}
}
}
What am I doing wrong here and how could I fix it? :) Thanks!!
NetworkOnMainThreadException: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
You should call sendfeedback method on asynctask then only above code will work. As webserver is taking lot of time to response main thread becomes unresponsive. To avoid it you should call it on another thread. Hence asynctask is better.
here is link that illustrates how to use asynctask
NetworkOnMainThreadException is thrown when your app tries networking operation in main thread.
To fix that you can use a private inner class within your Activity that extends android.os.AsyncTask<Params, Progress, Result> which will do the server call stuffs.
Something as,
private class SendfeedbackJob extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String[] params) {
// do above Server call here
return "some message";
}
#Override
protected void onPostExecute(String message) {
//process message
}
}
And then invoke above class from submit.setOnClickListener as below,
SendfeedbackJob job = new SendfeedbackJob();
job.execute(pass, email);
References
AsyncTask doc
AsyncTask Android example
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("myUrl");
// no idea what this does :)
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
// This is the line that send the request
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
}
catch (Exception e)
{
Log.e("log_tag", "Error in http connection "+e.toString());
}
Here is your problem. Since api 11, this exception will inform you that you are running long tasks on the ui thread (the http communication in your class), and according with the new StrictGuard policy this is not possibile. So you have two different choice
Use thread or aynctask in order to execut yout long term task (better way)
You made network call on main thread which is against to android rules, so you have to do your network call on separate thread like asynctask or handler etc.
You can just create Async class as below
class Retrievedata extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try{
//Your code
}
return null;
}
}
You can just put your all code inside doInBackground method
look at this link : https://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged.
if you set minSdkVersion <11, then your application will work and you can run network operation in main thread.
After a long research (lasted half day) I have found a solution for my problem which is similar to the problem indicated here. The exception displayed by my Android Studio 2.3.3 was this:
android studio android.os.networkonmainthreadexception
The problem was based on the impossibility to set a UI variable in the MainActivity. So I saw the following video and I solved my problem. I hope it is also useful to others:
How to avoid android os NetworkOnMainThreadException
Use thread for that case,
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
//Code here
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
As indicated here, AsyncTask is deprecated, and Google recommends you use the java.util.concurrent package or Kotlin coroutines
You can execute your network task in another thread very easily using java.util.concurrent.Executors.
Simply add these two variables to your LoginActivity class:
val executor = Executors.newSingleThreadExecutor()
Then surround your networking call with an executor.execute{} block:
executor.execute {
/**
* Executes network task in background. You cannot
* access view elements here.
*/
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent()
}
I am trying to input text from Android into websites, and I read that httppost is a good option. I download the HttpClient 4.2.2 (GA) tar.gz, unzipped them, and copied the 7 jars into the lib folder of my android project in Eclipse. I'm pretty sure I got all the jars, since they matched those listed on the website.
I then proceeded to copy and paste the top tutorial from: http://hc.apache.org/httpcomponents-client-ga/quickstart.html
I imported everything, and was left with this error:
EntityUtils.consume(entity1); //X
} finally {
httpGet.releaseConnection(); //X
This portion of code is at two places in the tutorial, and errors occur at both.
Eclipse says for the first line:
"The method consume(HttpEntity) is undefined for the type EntityUtils."
Second line:
"The method releaseConnection() is undefined for the type HttpGet."
I'm pretty sure I downloaded every jar, transported them correctly, and imported everything. What is making the error? Thanks.
Here is what I have now. Edward, I used some of the code from your methods, but just put them into onCreate. However, this isn't working. A few seconds after I go from the previous activity to this one, I get the message that the app "has stopped unexpectedly".
I have a question about inputting my Strings into the website text fields: Do I use NameValuePairs of HttpParams? Here's my code, can you see what's wrong? Thanks.
package com.example.myapp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;
public class BalanceCheckerActivity extends Activity {
private final String LOGIN_URL = "https://someloginsite.com"; //username and password
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_balance_checker);
String username = getIntent().getExtras().getString("username");
String password = getIntent().getExtras().getString("password");
//Building post parameters, key and value pair
List<NameValuePair> accountInfo = new ArrayList<NameValuePair>(2);
accountInfo.add(new BasicNameValuePair("inputEnterpriseId", username));
accountInfo.add(new BasicNameValuePair("password", password));
//Creating HTTP client
HttpClient httpClient = new DefaultHttpClient();
//Creating HTTP Post
HttpPost httpPost = new HttpPost(LOGIN_URL);
BasicHttpParams params = new BasicHttpParams();
params.setParameter("inputEnterpriseID", username);
params.setParameter("password", password);
httpPost.setParams(params);
//Url Encoding the POST parameters
try {
httpPost.setEntity(new UrlEncodedFormEntity(accountInfo));
}
catch (UnsupportedEncodingException e) {
// writing error to Log
e.printStackTrace();
startActivity(new Intent(this, AccountInputActivity.class));
}
HttpResponse response = null;
InputStreamReader iSR = null;
String source = null;
// Making HTTP Request
try {
response = httpClient.execute(httpPost);
// writing response to log
Log.d("Http Response:", response.toString());
iSR = new InputStreamReader(response.getEntity().getContent());
BufferedReader br = new BufferedReader(iSR);
source = "";
while((source = br.readLine()) != null)
{
source += br.readLine();
}
} catch (ClientProtocolException e) {
// writing exception to log
e.printStackTrace();
startActivity(new Intent(this, AccountInputActivity.class));
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
startActivity(new Intent(this, AccountInputActivity.class));
}
System.out.println(source);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_balance_checker, menu);
return true;
}
}
That mostly looks pretty good to me. I only saw one obviously wrong piece of code in it:
while((source = br.readLine()) != null)
{
source += br.readLine();
}
That's kind of a mess, and rather than try to untangle it, I'll just rewrite it.
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null)
sb.append(line);
String source = sb.toString();
Also, you shouldn't be doing network I/O from onCreate() or even from within your UI thread, since it can block for a long time, freezing your entire UI and possibly causing an "Application Not Responding" (ANR) crash. But for a simple test program, you can let that slide for now. For production code, you'd launch a thread or use AsyncTask().
Anyway, we're not really interested in building and debugging your program for you. Have you tried this code out? What was the result?
One final note: a login sequence like this is likely to return an authentication token in the form of a cookie. I forget how you extract cookies from an HttpResponse, but you'll want to do that, and then include any received cookies as part of any subsequent requests to that web site.
Original answer:
I think you've gotten yourself all tangled up. The Apache http client package is built into Android, so there's no need to download any jar files from apache.
I'm not familiar with EntityUtils, but whatever it is, if you can avoid using it, I would do so. Try to stick with the bundled API whenever possible; every third-party or utility library you add to your application increases bloat, and on mobile devices, you want to keep your application as light as possible. As for the actual "consume()" method not being found, that's probably a mistake in the documentation. They probably meant consumeContent().
The releaseConnection() call is probably only necessary for persistent connection. That's relatively advanced usage; I don't even do persistent or managed connections in my own code.
You haven't provided enough information to let us know what it is you're trying to do, but I'll try give you a reasonably generic answer.
There are many, many ways to transmit data to a server over the http protocol, but in the vast majority of cases you want to transmit form-encoded data via HttpPost.
The procedure is:
Create a DefaultHttpClient
Create an HttpPost request
Add headers as needed with setHeader() or addHeader().
Add the data to be transmitted in the form of an HttpEntity
Call client.execute() with the post request
Wait for and receive an HttpResponse; examine it for status code.
If you're expecting data back from the server, use response.getEntity()
There are many HttpEntity classes, which collect their data and transmit it to the server each in their own way. Assuming you're transmitting form-encoded data, then UrlEncodedFormEntity is the one you want. This entity takes a list of NameValuePair objects which it formats properly for form-encoded data and transmits it.
Here is some code I've written to do this; these are only code fragments so I'll leave it to you to incorporate them into your application and debug them yourself.
/**
* POST the given url, providing the given list of NameValuePairs
* #param url destination url
* #param data data, as a list of name/value pairs
*/
public HttpResponse post(String url, List<NameValuePair> data) {
HttpPost req = new HttpPost(url);
UrlEncodedFormEntity e;
try {
e = new UrlEncodedFormEntity(data, "UTF-8");
} catch (UnsupportedEncodingException e1) {
Log.e(TAG, "Unknown exception: " + e1);
return null; // Or throw an exception, it's up to you
}
return post(req, e);
}
/**
* Post an arbitrary entity.
* #param req HttpPost
* #param data Any HttpEntity subclass
* #return HttpResponse from server
*/
public HttpResponse post(HttpPost req, HttpEntity data) {
try {
HttpClient client = new DefaultHttpClient();
req.setEntity(data);
HttpResponse resp = client.execute(req);
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK) {
Log.w(TAG,
"http error: " + resp.getStatusLine().getReasonPhrase());
return null; // Or throw an exception, it's up to you
}
return resp;
} catch (ClientProtocolException e) {
Log.e(TAG, "Protocol exception: " + e);
return null;
} catch (UnknownHostException e) {
return null;
} catch (IOException e) {
Log.e(TAG, "IO exception: " + e);
return null;
} catch (Exception e) {
// Catch-all
Log.e(TAG, "Unknown exception: " + e);
return null;
}
}
I am developing an android application where in each activity i need to pass some data onto the server and get back the responses before going to the next activity. The application works fine if the internet is fast enough. But as the speed goes down the application force closes. How to deal with slow internet connection so that it might not lead to force close of application?????
Here is some part of code
public void onClick(View v) {
// TODO Auto-generated method stub
UserFunctions userFunction = new UserFunctions();
if(userFunction.isNetworkAvailable(getApplicationContext()))
{
answer="";
for(int check1=0;check1<counter2;check1++){
int check2=0;
answer=answer+option4[check1]+"|";
while(check2<counter1){
if(edTxt[check1][check2].getText().toString().equals("")){
answer="";
break;
}
else{
answer=answer+edTxt[check1][check2].getText().toString()+"|";
}
check2++;
}
if(answer.equals("")){
break;
}
else{
answer=answer+"||";
}
}
if(answer.equals("")){
Toast.makeText(this, "Please fill all fields", 600).show();
}
else{
userFunction.form1(surveyId,userId , quesNo, answer);
if(total>0){
draw(temp);
}
else{
ques_no++;
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("quesNo", Integer.toString(ques_no)));
params.add(new BasicNameValuePair("surveyId", surveyId));
count = getJsonFromURL22(surveyCond, params);
j=Integer.parseInt(result);
if(j==22)
{
Toast.makeText(this, "Survey Completed", 600).show();
Intent home=new Intent(Format16.this, SurveyCompleted.class);
UserFunctions userFunctions = new UserFunctions();
userFunctions.full(surveyId);
Bundle d=new Bundle();
d.putString("userId", userId);
home.putExtras(d);
startActivity(home);
}
public String getJsonFromURL22(String url, List<NameValuePair> params){
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(params));
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);
sb = new StringBuilder();
sb.append(reader.readLine());
String line="0";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
is.close();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
return result;
}
Since you have not shown any code, I am guessing you are targeting Android API level 10 or lower, and you are doing all the networking in the UI thread, resulting in the dreaded App Not Responding(ANR) error. One way to fix the problem would be to use AsyncTask and move all your networking code in there. When done right, AsyncTask's doInBackground() will process all your networking in a separate thread, allowing the UI to remain responsive.
It usually works something like this:
private class NetworkTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// Do all networking here, this will work away in a background thread.
// In your case:
// HttpResponse response = httpclient.execute(httppost);
// Must happen here
}
#Override
protected void onPostExecute(String result) {
// dismiss progress dialog if any (not required, runs in UI thread)
}
#Override
protected void onPreExecute() {
// show progress dialog if any, and other initialization (not required, runs in UI thread)
}
#Override
protected void onProgressUpdate(Void... values) {
// update progress, and other initialization (not required, runs in UI thread)
}
}
If you enable StrictMode, or target api versions 11 and higher, Android will throw a NetworkOnMainThreadException when you try to do this.
The application works fine if the internet is fast enough. But as the
speed goes down the application force closes.
It clearly indicates that you are doing network operation on UI Thread.As per Google Docs if the Asynchronous operation is performed on Main thread and if it is taking more than 5 seconds then your application will show force close dialog which is very unpleasent for end user.
In-fact if you try to run such application on latest android version (i.e 4.0 or later) It will not allow you to run application it will crash at start as soon as it detects that the asynchronous operation is performed on main thread.
You must use AsyncTask or Handlers to perform long running application.
Go through following blog to know more.
http://android-developers.blogspot.in/2010/07/multithreading-for-performance.html
That must be ANR issue not the Force Close issue.
You can use StrictMode to help find potentially long running operations such as network that you might accidentally be doing your main thread.
Or else try to put progress bar.
use setConnectionTimeout or setSoTimeout for handling connection timeout.
HttpGet httpGet = new HttpGet(url);
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);
and use AsyncTask or Handler or HandlerThread or runOnUiThread anyone for getting data from Server(to perform long running task in background).
You should take a look at this tool that allows you to see what is causing the slow down in your application. The ARO tool is designed to diagnose these sorts of network problems http://developer.att.com/developer/forward.jsp?passedItemId=9700312
I have this exception and I was reading a thread on this, and it seemed confusing:
How to fix android.os.NetworkOnMainThreadException?
I already added this line to my manifest:
<uses-permission android:name="android.permission.INTERNET" />
On that discussion, they talk about the main execution thread of the app not being able to do networking. What I am wondering is how to restructure my code so that it is inline with Android good practices.
Here is my Activity class for this:
package com.problemio;
import java.io.InputStream;
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 android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class LoginActivity extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
// Show form for login_email
final EditText loginEmail = (EditText) findViewById(R.id.login_email);
String name = loginEmail.getText().toString();
// Show field for password
final EditText password = (EditText) findViewById(R.id.password);
String text = password.getText().toString();
// Show button for submit
Button submit = (Button)findViewById(R.id.submit);
// Show options for create-profile and forgot-password
submit.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
String email = loginEmail.getText().toString();
String pass = password.getText().toString();
sendFeedback(pass, email);
}
});
}
public void sendFeedback(String pass , String email)
{
Log.d( "1" , pass );
Log.d( "1" , email );
// Go to db and check if these r legit
// How do I do that? :)
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("username", email ));
postParameters.add(new BasicNameValuePair("password", pass ));
String responseString = null;
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("myUrl");
// no idea what this does :)
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
// This is the line that send the request
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
}
catch (Exception e)
{
Log.e("log_tag", "Error in http connection "+e.toString());
}
}
}
What am I doing wrong here and how could I fix it? :) Thanks!!
NetworkOnMainThreadException: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
You should call sendfeedback method on asynctask then only above code will work. As webserver is taking lot of time to response main thread becomes unresponsive. To avoid it you should call it on another thread. Hence asynctask is better.
here is link that illustrates how to use asynctask
NetworkOnMainThreadException is thrown when your app tries networking operation in main thread.
To fix that you can use a private inner class within your Activity that extends android.os.AsyncTask<Params, Progress, Result> which will do the server call stuffs.
Something as,
private class SendfeedbackJob extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String[] params) {
// do above Server call here
return "some message";
}
#Override
protected void onPostExecute(String message) {
//process message
}
}
And then invoke above class from submit.setOnClickListener as below,
SendfeedbackJob job = new SendfeedbackJob();
job.execute(pass, email);
References
AsyncTask doc
AsyncTask Android example
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("myUrl");
// no idea what this does :)
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
// This is the line that send the request
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
}
catch (Exception e)
{
Log.e("log_tag", "Error in http connection "+e.toString());
}
Here is your problem. Since api 11, this exception will inform you that you are running long tasks on the ui thread (the http communication in your class), and according with the new StrictGuard policy this is not possibile. So you have two different choice
Use thread or aynctask in order to execut yout long term task (better way)
You made network call on main thread which is against to android rules, so you have to do your network call on separate thread like asynctask or handler etc.
You can just create Async class as below
class Retrievedata extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try{
//Your code
}
return null;
}
}
You can just put your all code inside doInBackground method
look at this link : https://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged.
if you set minSdkVersion <11, then your application will work and you can run network operation in main thread.
After a long research (lasted half day) I have found a solution for my problem which is similar to the problem indicated here. The exception displayed by my Android Studio 2.3.3 was this:
android studio android.os.networkonmainthreadexception
The problem was based on the impossibility to set a UI variable in the MainActivity. So I saw the following video and I solved my problem. I hope it is also useful to others:
How to avoid android os NetworkOnMainThreadException
Use thread for that case,
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
//Code here
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
As indicated here, AsyncTask is deprecated, and Google recommends you use the java.util.concurrent package or Kotlin coroutines
You can execute your network task in another thread very easily using java.util.concurrent.Executors.
Simply add these two variables to your LoginActivity class:
val executor = Executors.newSingleThreadExecutor()
Then surround your networking call with an executor.execute{} block:
executor.execute {
/**
* Executes network task in background. You cannot
* access view elements here.
*/
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent()
}
I have "BackUpContacts.db" database in SQLiteDatabase, it has a table named "ContactInfo" with column names ContactId, ContactName, MobilePhone1, MobilePhone2, OfficePhone1, OfficePhone2, OfficePhone3, HomePhone1, HomePhone2 and TokenId.
What i want is to transfer all data of "ContactInfo" table to the mysql database system at some server (means server has also a table similar to "ContactInfo", where all data of "ContactInfo" will be copied).
The last important thing which i want is that, whenever i want to get contacts(of a specified TokenId) i can backup all those from server to the mobile device in an xml file.
in short, can here anyone help me how to transfer sqlite db to a web server?
One way is to submit data to your webiste's php page by using GET or POST method which will add it to MySql on your remote application server, like
HttpGet request = new HttpGet(url);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
HttpClient client = new DefaultHttpClient();
String response = client.execute(request, responseHandler);
url can be: www.mysite.com?id=5&name=john ...
This also has to be an AsyncTask doInBackground request...
The problem is how many records can be uploaded at once...
It easy to make the remote application server produce an XML file on request to be downloaded by android, with a similar request like above.
This is an example how to upload an XML file from http://w3mentor.com/learn/java/android-development/android-http-services/example-of-multipart-post-using-android/
Where data.xml file and two more fields ("one" and "two") are uploaded to the server. Note that this will require additional jar libraries which you need to download and place in the "lib" folder on the same level as "res" and and "src" folders in the project.
Here are the three jar files you need httpmime-4.0.jar, apache-mime4j-0.6.jar, commons-io-1.4.jar:
http://james.apache.org/download.cgi#Apache_Mime4J
https://repository.apache.org/content/repositories/releases/org/apache/httpcomponents/httpmime/4.0.1/httpmime-4.0.1.jar
http://code.google.com/p/mapmap/downloads/detail?name=commons-io-1.4.jar&can=2&q=
You add this to the project by selecting the project in Exclipse and click File>Properties>Java Build Path>Libraries and then [Add jars]
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
public class TestMultipartPost extends Activity
{
public void executeMultipartPost()throws Exception
{
try {
InputStream is = this.getAssets().open("data.xml");
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("http://w3mentor.com/Upload.aspx");
byte[] data = IOUtils.toByteArray(is);
InputStreamBody isb = new InputStreamBody(new ByteArrayInputStream(data),"uploadedFile");
StringBody sb1 = new StringBody("someTextGoesHere");
StringBody sb2 = new StringBody("someTextGoesHere too");
MultipartEntity multipartContent = new MultipartEntity();
multipartContent.addPart("uploadedFile", isb);
multipartContent.addPart("one", sb1);
multipartContent.addPart("two", sb2);
postRequest.setEntity(multipartContent);
HttpResponse res = httpClient.execute(postRequest);
res.getEntity().getContent().close();
} catch (Throwable e)
{
// handle exception here
}
}
}
One more thing, you need to run this in the "background" as an asynchronous task like this:
private class XmlUploadTask extends AsyncTask<Object, String, Boolean> {
private static final String DEBUG_TAG = "XmlUploadTask";
ProgressDialog pleaseWaitDialog;
#Override
protected void onCancelled() {
Log.i(DEBUG_TAG, "onCancelled");
pleaseWaitDialog.dismiss();
}
#Override
protected void onPostExecute(Boolean result) {
Log.i(DEBUG_TAG, "onPostExecute");
pleaseWaitDialog.dismiss();
}
#Override
protected void onPreExecute() {
pleaseWaitDialog = ProgressDialog.show(myActivity.this, "My Application", "Uploading data...", true, true);
pleaseWaitDialog.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface dialog) {
XmlUploadTask.this.cancel(true);
}
});
}
#Override
protected Boolean doInBackground(Object... params) {
//here you enter the xml upload code above
return null;
}
}
Another way which i found over web that how to send xml file to a web server:
For this you need to add a jar file "commons-httpclient.jar" in your project. (How to add jar file is clearly mentioned by ChristianB in above/below post)
You can download this jar file from http://www.java2s.com/Code/Jar/ABC/Downloadcommonshttpclientjar.htm
2.code would be...
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import java.io.File;
import java.io.FileInputStream;
class ClassName extends Activity
{
public void Sync(View v) // on button click
{
File xmlFile = new File("sdcard/contacts.xml");
FileInputStream fis = new FileInputStream(xmlFile);
InputStreamRequestEntity isre = new InputStreamRequestEntity(fis);
/*now pass url of server in constructor of PostMethod*/
PostMethod post = new PostMethod("http://w3mentor.com/Upload.aspx");
post.setRequestEntity(isre);
post.setRequestHeader("Content-Type", "text/xml");
HttpClient httpclient = new HttpClient();
int response = httpclient.executeMethod(post);
String res = post.getResponseBodyAsString();
Toast.makeText(GetContacts.this, new Integer(response).toString()+" "+res, Toast.LENGTH_LONG).show();
post.releaseConnection();
}
}