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();
}
}
Related
Now am building an android application where i want the user to upload video to the server, then after uploading it, it should appear on the MainActivity, I've set up the login/register using Firebase but Firebase doesn't support streaming Videos(according to my attempts), thus i've been googling for long time about servers and how servers work with video uploading and streaming but i've reached an end point.
What i want to do is, building a system where user can upload a video from his local device, into a server, and then downloading(video streaming from a server), so the user later on can interact with it. I am not sure how to do it, i have searched a lot but couldn't find what i needed to do/learn
How you upload the video and how you make it available are really two separate questions.
For uploading from Android:
There are a number of libraries you can use to upload to Android - the code below uses the apache multipart client and it is tested and works. Other http libraries include Volley and retrofit.
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.os.AsyncTask;
import android.util.Log;
public class VideoUploadTask extends AsyncTask<String, String, Integer> {
/* This Class is an AsynchTask to upload a video to a server on a background thread
*
*/
private VideoUploadTaskListener thisTaskListener;
private String serverURL;
private String videoPath;
public VideoUploadTask(VideoUploadTaskListener ourListener) {
//Constructor
Log.d("VideoUploadTask","constructor");
//Set the listener
thisTaskListener = ourListener;
}
#Override
protected Integer doInBackground(String... params) {
//Upload the video in the background
Log.d("VideoUploadTask","doInBackground");
//Get the Server URL and the local video path from the parameters
if (params.length == 2) {
serverURL = params[0];
videoPath = params[1];
} else {
//One or all of the params are not present - log an error and return
Log.d("VideoUploadTask doInBackground","One or all of the params are not present");
return -1;
}
//Create a new Multipart HTTP request to upload the video
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(serverURL);
//Create a Multipart entity and add the parts to it
try {
Log.d("VideoUploadTask doInBackground","Building the request for file: " + videoPath);
FileBody filebodyVideo = new FileBody(new File(videoPath));
StringBody title = new StringBody("Filename:" + videoPath);
StringBody description = new StringBody("Test Video");
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("videoFile", filebodyVideo);
reqEntity.addPart("title", title);
reqEntity.addPart("description", description);
httppost.setEntity(reqEntity);
} catch (UnsupportedEncodingException e1) {
//Log the error
Log.d("VideoUploadTask doInBackground","UnsupportedEncodingException error when setting StringBody for title or description");
e1.printStackTrace();
return -1;
}
//Send the request to the server
HttpResponse serverResponse = null;
try {
Log.d("VideoUploadTask doInBackground","Sending the Request");
serverResponse = httpclient.execute( httppost );
} catch (ClientProtocolException e) {
//Log the error
Log.d("VideoUploadTask doInBackground","ClientProtocolException");
e.printStackTrace();
} catch (IOException e) {
//Log the error
Log.d("VideoUploadTask doInBackground","IOException");
e.printStackTrace();
}
//Check the response code
Log.d("VideoUploadTask doInBackground","Checking the response code");
if (serverResponse != null) {
Log.d("VideoUploadTask doInBackground","ServerRespone" + serverResponse.getStatusLine());
HttpEntity responseEntity = serverResponse.getEntity( );
if (responseEntity != null) {
//log the response code and consume the content
Log.d("VideoUploadTask doInBackground","responseEntity is not null");
try {
responseEntity.consumeContent( );
} catch (IOException e) {
//Log the (further...) error...
Log.d("VideoUploadTask doInBackground","IOexception consuming content");
e.printStackTrace();
}
}
} else {
//Log that response code was null
Log.d("VideoUploadTask doInBackground","serverResponse = null");
return -1;
}
//Shut down the connection manager
httpclient.getConnectionManager( ).shutdown( );
return 1;
}
#Override
protected void onPostExecute(Integer result) {
//Check the return code and update the listener
Log.d("VideoUploadTask onPostExecute","updating listener after execution");
thisTaskListener.onUploadFinished(result);
}
To make the video available on the server side you just need a HTTP server that can server static content or a video streaming server - the latter will allow you use Adaptive Bit Rate Streaming (ABR - e.g. HLS or DASH) for better quality, but may be overkill for your needs.
Either approach will provide you withe a URL for the video which you can use an Android player like ExoPlayer to play back the video with:
https://github.com/google/ExoPlayer
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()
}
Connect an Android Device To a Web Service on Local Host
Following my previous thread , im now able to connect my Android Device to my local host using wamp
But still i cannot connect to my symfony server and get my API datas
I sarted symfony's internal server :
"Server running on http://127.0.0.1:8000"
I used Internet permission on my AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
My MainActivity.java code
package com.example.cbmedandroid;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.my_button).setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
Button b = (Button)findViewById(R.id.my_button);
b.setClickable(false);
new LongRunningGetIO().execute();
}
private class LongRunningGetIO extends AsyncTask <Void, Void, String> {
protected String getASCIIContentFromEntity(HttpEntity entity) throws IllegalStateException, IOException {
InputStream in = entity.getContent();
StringBuffer out = new StringBuffer();
int n = 1;
while (n>0) {
byte[] b = new byte[4096];
n = in.read(b);
if (n>0) out.append(new String(b, 0, n));
}
return out.toString();
}
#Override
protected String doInBackground(Void... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://192.168.43.13:8000/api/horaire.json");
String text = null;
try {
HttpResponse response = httpClient.execute(httpGet, localContext);
HttpEntity entity = response.getEntity();
text = getASCIIContentFromEntity(entity);
} catch (Exception e) {
return e.getLocalizedMessage();
}
return text;
}
protected void onPostExecute(String results) {
if (results!=null) {
EditText et = (EditText)findViewById(R.id.my_edit);
et.setText(results);
}
Button b = (Button)findViewById(R.id.my_button);
b.setClickable(true);
}
}
}
When i launch the application and click to the button .
It load during 40 sec and i get this
"Connection to http://192.168.43.13:8000 refused"
192.168.43.13 is my pc adress
What should i do to fix this .
thanks.
FINALLY! i have found the solution to my problem
when running the built-in php server .
We need to specify this command
php bin/console server:run 0.0.0.0:8000
(8000 is my port , you can put yours)
so that Any device or host (ip) could access
if you put 127.0.0.1 only your localhost will be allowed
That's why i couldn't get the Api even i was connected to my localhost via wifi hotspot
It's ok now
Are you able to install this cURL App for Android?
Then use on your Android (is this a real phone or an emulator) open a cURL window and then enter:
cURL http://192.168.43.13:8000/
I tried this same kind of setup with a real Android phone and the above indicated cURL app and put in my Symfony web URL (on another PC), and the Android shows the correct html response back that I'm expecting.
At least this will help you verify functionality first.
Edit below this line:
Here is the code you might use since HttpClient was deprecated:
URL url = new URL("http://192.168.43.13:8000/api/horaire.json");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//conn.setRequestMethod("GET");
// read the response
System.out.println("Response Code: " + conn.getResponseCode());
InputStream in = new BufferedInputStream(conn.getInputStream());
String response = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
System.out.println(response);
Not sure if you need to use the "setRequestMethod". But try out this change and see if that works for you.
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 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()
}