Submit form with POST data in Android app - android

I've been searching the web for a way to do this for about a week now, and I just can't seem to figure it out.
I'm trying to implement an app that my college can use to allow users to log in to various services on the campus with ease. The way it works currently is they go to an online portal, select which service they want, fill in their user name and pwd, and click login. The form data is sent via post (it includes several hidden values as well as just the user name and pwd) to the corresponding login script which then signs them in and loads the service.
I've been trying to come at the problem in two ways. I first tried a WebView, but it doesn't seem to want to support all of the html that normally makes this form work. I get all of the elements I need, fields for user and pwd as well as a login button, but clicking the button doesn't do anything. I wondered if I needed to add an onclick handler for it, but I can't see how as the button is implemented in the html of the webview not using a separate android element.
The other possibility was using the xml widgets to create the form in a nice relative layout, which seems to load faster and looks better on the android screen. I used EditText fields for the input, a spinner widget for the service select, and the button widget for the login. I know how to make the onclick and item select handlers for the button and spinner, respectively, but I can't figure out how to send that data via POST in an intent that would then launch a browser. I can do an intent with the action url, but can't get the POST data to feed into it.
So here is what I have right now...
HttpParams params = new BasicHttpParams();
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost(action);
String endResult = null;
try
{
post.setEntity(new UrlEncodedFormEntity(myList));
}
catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
String response = client.execute(post, new BasicResponseHandler());
endResult = response;
}
catch (ClientProtocolException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
So my question now... is how do I take the endResult screen, which should be the page returned after I logged in to my service, and display it in a browser?

What's wrong with them just using the built in browser? You can also submit a form using UrlEncodedFormEntity and HttpClient.
HttpParams params = new DefaultHttpParams(); // setup whatever params you what
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost("someurl");
post.setEntity(new UrlEncodedFormEntity()); // with list of key-value pairs
client.execute(post, new ResponseHandler(){}); // implement ResponseHandler to handle response correctly.
Okay and after you have the response in a string. The response since its a page is going to be in html. You need to use a WebView to show the html. WebView has a method loadData() that takes a string of html and displays it.

Based on #RobbyPonds answer, for the benefit of people wandering past here, below is a generic implementation to post and receive a response from a URI (NOTE Also contains waiting implementation to return a response, probably not every day implementation of network call):
private static String responseValue;
#SuppressWarnings({ "unchecked", "rawtypes" })
public static String sendPostToTargetAndWaitForResponse() throws ClientProtocolException, IOException {
final Thread currentThread = Thread.currentThread();
synchronized (currentThread) {
HttpParams params = new BasicHttpParams();
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost(HTTP_POST_URI);
// List Creation with post data for UrlEncodedFormEntity
ArrayList<NameValuePair> mList = new ArrayList<NameValuePair>();
mList.add(new NameValuePair() {
#Override
public String getValue() {
return getSampleJSON();
}
#Override
public String getName() {
return "json";
}
});
post.setEntity(new UrlEncodedFormEntity(mList)); // with list of key-value pairs
client.execute(post, new ResponseHandler(){
#Override
public Object handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
responseValue = EntityUtils.toString(response.getEntity(), "UTF-8");
synchronized (currentThread) {
currentThread.notify();
}
return null;
}
});
try {
currentThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return responseValue;
}
}

Related

how to send a HTTP SEARCH request in HttpURLConnection on Android?

I want to know if it is possible to send SEARCH request (practically) through java.net.HttpURLConnection to HTTP-based URL.
I have read so many articles describing that how to send GET, POST, DELETE requests but I still haven't found any sample code which successfully performs SEARCH request.
here is sample code.
public static String HTTPSearch(String urlAddress, String... searchDataPair) {
HttpParams myParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(myParams, 10000);
HttpConnectionParams.setSoTimeout(myParams, 30000);
DefaultHttpClient hc = new DefaultHttpClient(myParams);
ResponseHandler<String> res = new BasicResponseHandler();
HttpSearch searchMethod = new HttpSearch (urlAddress);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
putDataPair.length / 2);
for (int i = 0; i < putDataPair.length; i += 2) {
nameValuePairs.add(new BasicNameValuePair(searchDataPair[i],
searchDataPair[i + 1]));
}
String response = "";
try {
searchMethod .setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = hc.execute(searchMethod , res);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
in this code, HttpSearch is error.
please help me about HttpSearch.
First, i dont know whether my approach is best or not.
Im using restful codeigniter webservice. What i did to implement search is by using POST. I simply POST the search keyword and then my webservice will perform SQL Query to search that String (keyword) im my database.
According to the docs, the setRequestMethod() does not allow for the SEARCH method (which makes sense, since from what I can tell SEARCH is MS only. However, you can always try to use setRequestMethod() and see what happens.

RESTful web Service for Android Application

I have an application and I need to get some data from my database(MySQL and it stays on web, not local). I think a simple RestFul webservice will be the best option for me to access this database and get the data. However, I m not able to create the webservice. I did some researches but I got confused. All I need is just accessing the database and get a few data from the table. Please give me some help to create the neccessary webservice. I don't want it to be a complex webservice. Thank to you all
this is php page of web-service. in this userid is taken from android java file that requesting that data. and after that selecting data from mySql it will simply echo all data and that will be given to java file as response.
seluser_profile.php
<?php
//$con=mysql_connect("localhost","root","");
//mysql_select_db("android_db",$con);
$con=mysql_connect("localhost","root","");
mysql_select_db("android_db",$con);
$uname=$_POST['userid'];
$q="select * from user_details where username='$uname'";
$rec=mysql_query($q);
if(mysql_num_rows($rec)==1)
{
$arr=mysql_fetch_array($rec);
echo $arr[0]+" "+$arr[2]+" "+$arr[3];
}
else
{
echo "false";
}
?>
Java code for requesting to web service.
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.0.2/webservice/seluser_profile.php");
try {
// Add your data
//Toast.makeText(getApplicationContext(), "Hello", Toast.LENGTH_LONG).show();
List<NameValuePair> namevpair = new ArrayList<NameValuePair>(2);
namevpair.add(new BasicNameValuePair("userid",valueIWantToSend));//in this first argument is name of post variable which we will use in php web service as name of post varible $_POST['fname'];
httppost.setEntity(new UrlEncodedFormEntity(namevpair));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
str = inputStreamToString(response.getEntity().getContent()).toString();
//Toast.makeText(getApplicationContext(), "your answer="+str, Toast.LENGTH_LONG).show();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
use this java code in doInBackground method of Asynctask class. otherwise it will give you network handler exception.
private StringBuilder inputStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Return full string
return total;
}
and also add this function for string building from inputstream.
Here is a link, You may seen this while surfing, I know this is not an answer , but I cannot comment bcz I dnt have enough Rep.
http://www.androidhive.info/2014/01/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-12-2/
I used this in one of my project, customization was very easy..and a great tutorial.

How to login and keep cookie for later use of a webpage

So, I have this webpage which I want to access, but first I have to login from another webpage. I want to keep the cookies and then use it for later automatic login. So far what I did:
First, this is the login webpage: https://autenticacao.uvanet.br/autenticacao/pages/login.jsf
It's my university's student's area.
public class Consulta extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
StringBuilder builder = new StringBuilder(100000);
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(urls[0]);
try {
List<NameValuePair> val = new ArrayList<NameValuePair>(2);
val.add(new BasicNameValuePair("form:usuario", "myusername"));
val.add(new BasicNameValuePair("form:senha", "mypass"));
httpPost.setEntity(new UrlEncodedFormEntity(val));
HttpResponse response = client.execute(httpPost);
InputStream content = response.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
builder.append(s);
}
} catch (Exception e) {
e.printStackTrace();
}
return builder.toString();
}
}
This is the class I use to make the HttpPost and this is how I call it:
#Override
public void onClick(View v) {
try{
String html = new Consulta().execute("https://autenticacao.uvanet.br/autenticacao/pages/login.jsf").get();
Document doc = Jsoup.parse(html);
Element link = doc.select("title").first();
String t = link.text();
tv1.setText(t);
}catch(Exception e){
e.printStackTrace();
}
}
I believed it would work this way:
I send the webpage to login to Consulta.java
The class would get the fields "form:usuario" and "form:senha" and fill them with myusername and mypassword and then login
The class would return me html code of the second webpage as string
But what happens is that it returns me the first webpage (the login one). I'm pretty sure I'm doing something wrong, but I don't know what, could someone help me? Also, sorry for my english, it's not my main language.
When you do the login (in https://autenticacao.uvanet.br/autenticacao/pages/login.jsf), I don't think the response is the html code of the second webpage. Are you sure about this?
I think the normal behavior for a login page is to respond with the same page (the login one) but adding the session cookie and the header to do a redirect to the second webpage, but not the second page itself.
In this case, you have to read the http header response to extract these parameters: the cookies and the URL of the second webpage.
Using the object HttpResponse:
Header[] h = response.getAllHeaders();
But I recommend you to use HttpURLConnection class instead of DefaultHttpClient.

Post Params not being sent to web server using HttpPost

For some reason I can not get my async task to pass along the post params I set. Any help is appreciated.
Here is my onClick which calls the thread. Please note that customerInfo is not null, and each index has a value.
EDITED: moved client and post declaration into doInBackground and took out extra, unneeded thread.
EDITED2: Apparently when hitting a subdirectory on your web server, and you declare your url like
http://IP/subDirectory
without the trailing "/" apache doesn't pass the parameter to your index.php.
#Override
public void onClick(View v) {
new RegisterPost(progress).execute();
}
Here is my doInBackground
#Override
protected Void doInBackground(Void... voids) {
String[] customerInfo = getRegistrationInfo();
// Post
// Send info to tmiszone
String url = "http://SERVER_ADDRESS/"; // I had to add index.php to my url to get around the issue.
client = new DefaultHttpClient();
post = new HttpPost(url);
// Set post parameters
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
pairs.add(new BasicNameValuePair("salesCode", customerInfo[0]));
pairs.add(new BasicNameValuePair("firstName", customerInfo[1]));
pairs.add(new BasicNameValuePair("lastName", customerInfo[2]));
try {
post.setEntity(new UrlEncodedFormEntity(pairs));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// Make connection
try {
response = client.execute(post);
} catch (ClientProtocolException e){
// TODO handle
response = null;
} catch (IOException e) {
// TODO handle
response = null;
} catch (Exception e) {
// TODO handle
response = null;
}
return null;
}
Here is my php code.
<html>
<body>
<?php
error_log("hit by app");
foreach($_POST as $key=>$value){
error_log("// ".$key." ".$value);
}
?>
</body>
</html>
Now in my apache log I see the "hit by app" message, but nothing else. And my app gets an empty html page with just the html and body tags as expected from the php code.
The problem I faced had to do with my URL. my url was like
http://ip_address/testbed
the page I was hitting was index.php inside the testbed directory. Since I didn't put trailing "/" apache wasn't sending the parameters to the page during the automatic redirect. Add the "/" resolved the issue. Thank you Sam_D for your help.

How do I set an alert based on the HTML Text in android

currently I'm pulling text from a website using
public String getText(String uri) {
HttpClient client1 = new DefaultHttpClient();
HttpGet request = new HttpGet(uri);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
try {
String response_str = client1.execute(request, responseHandler);
return response_str;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
}
and I get a bunch of HTML code that is filtered with Html.fromHtml() which cleans up all the HTML text and leaves me with the dialog I want.
However this method cannot let me set the title of the alert dialog because it only comes out as one string and cannot differentiate between whats in the parameters from the <body></body> parameters. It also doesn't filter out some comments such as
<!--BODY{color:white; background-color:transparent;......
How can I delete the extra HTML text and separate the title portion from the main body of the text. Thank You
Take a look at Spannable string class.
"This is the interface for text to which markup objects can be attached
and detached. Not all Spannable classes have mutable text; see
Editable for that."
To parse HTML, use an HTML-Parser as there are some out there.
In the case that you control the formating/content of that pulled/desired HTML-Page, you'll want to switch from HTML to something better suited for your needs like a simple XML-Language or JSON.

Categories

Resources