I am almost dead doing this.Need help.
My Requirement :-
I am developing an android app and want to use the cookies(/session) from webview in my java code. I basically want to get the html of other pages of an url after login in webview without opening those pages in webview but through my java code.
What I tried :-
For this I tried HttpClient and HttpURLConnection referring many SO questions but failed.
Can anybody please give me a sample code?
Say I have cookies in a hashmap cookies. How Can I use HttpClient and HttpURLConnection or anything else to get the other page html. The website I am trying with is https:
Please give a sample code
If I am right u are trying to use your webview's cookies to get other pages of site in your activity java code.if yes try this:
BufferedReader reader = null;
try {
URL url2 = new URL("url");
URLConnection con = (URLConnection) url2.openConnection();
CookieManager.getInstance().setAcceptCookie(true);
con.setRequestProperty("Cookie",CookieManager.getInstance().getCookie("logged in url in webview"));
con.setDoOutput(true);
con.connect();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBiffer html;
String line = "";
while ((line = reader.readLine()) != null) {
html.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
It worked for me.
Have you tried to add the cookie as a HTTP header? I am not sure if I have understood you right but you can consider these:
Cookies: If you want to load some resource (no matter if it is a web page, image, css, js or something else) you are making a HTTP request. If the server keeps a session for your user, you are probably given a session cookie. The cookie must be sent with each request to the server as e COOKIE header. So if you want to pass the cookie to your request, add it as a header. Android provides you an easy way to do this with the CookieManager class. You can refer to this.
SSL: If you are trying to access a secured web site (https) you have to use an SSL certificate. Android comes up with a bunch of predistributed certificates for most of the popular web cites (e.g Facebook, Google, Twitter, etc.). You can use them out of the box. If your SSL certificate is not presented, you have to add it manually. Read this for more information.
I hope this was useful :)
Related
I have this scenario which my app shows in a webView a 2-page login process.
The first page asks only to which domain to you plan on connecting.
The second page asks for the credentials.
I'm trying to perform the login in the webView and then execute requests from my native code.
I realize I need to get the stored cookie from the webView (but from which url? from the first page or the second one?), and then use the cookie for the native code requests.
Can someone please tell me how to go about it? The login process is easy - the user logs in through the webview - fine. Now, I know how to use the cookie manage but I dont know which cookie am I suppose to look for - is it the url of the first login page? is it the second one? does it matter?
Next, how do I use the cookie to send back to server with a GET request so the server will know I'm authenticated?
I appreciate the answers I'm clueless and begging for help :)
Since the accepted answer does not really describe how it is done:
Put these lines somewhere where your app starts:
CookieHandler.setDefault(new CookieManager()); // Apparently for some folks this line works already, for me on Android 17 it does not.
CookieSyncManager.createInstance(yourContext); // or app will crash when requesting cookie
And then in your connection:
String cookies = CookieManager.getInstance().getCookie(urlString);
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
// conn.setRequestMethod("GET");
// conn.setDoInput(true);
if (cookies != null)
conn.setRequestProperty("Cookie", cookies);
// Starts the query
conn.connect();
I have done the opposite of you: I log in with loopj Android Asynchronous Http Client, and want the session cookies to apply to a webview, for the same website. I don't know if it will help you, but, I am going to post my code for copying over the cookies. Maybe seeing the process will help you to look for the items you need... to copy cookies from webview, to HTTP. I can't offer further help, since I'm fairly new at Android. (And, of course, I adapted my code from other people's posts.)
Class variable declarations:
private AsyncHttpClient loopjClient = new AsyncHttpClient();
private PersistentCookieStore myCookieStore;
onCreate() initialization:
myCookieStore = new PersistentCookieStore(this);
loopjClient.setCookieStore(myCookieStore);
After HTTP login:
// get cookies from the generic http session, and copy them to the webview
CookieSyncManager.createInstance(getActivity().getApplicationContext());
CookieManager.getInstance().removeAllCookie();
CookieManager cookieManager = CookieManager.getInstance();
List<Cookie> cookies = myCookieStore.getCookies();
for (Cookie eachCookie : cookies) {
String cookieString = eachCookie.getName() + "=" + eachCookie.getValue();
cookieManager.setCookie("http://www.example.com", cookieString);
//System.err.println(">>>>> " + "cookie: " + cookieString);
}
CookieSyncManager.getInstance().sync();
// holy ****, it worked; I am automatically logged in for the webview session
Note that loopj is like the webview, in that all cookie management and sending are automatic. I just copy all cookies for the domain. I think you'd be fine, doing the same... thus, no worry about whether from the first or second page.
At the end I found my way and it was pretty simple.
Once the user logs in through the webview - a cookie is set on the device.
Later on once I want to perform Native api calls on the service I ask the cookie manager for the cookie that was set based on the url.
I then take the important header that is used to authenticate on the server and send it along with my api calls.
Has anyone released code to show the full HTTP request/response headers, any intermediate redirects, and any cookie data for the Android HttpURLConnection? This would be similar to Firefox Web Console
I roughly know how to write this myself, but 1) it's a non-trivial amount of code 2) it's tricky to get this kind of code to work in all instances. So i'm interested in finding a readymade solution. I know how to tcpdump the emulator, but I'm searching for code to print this information into the Android Log class for really quick runtime debugging.
for header fields
URL url = new URL(str_url);
HttpURLConnection conection = (HttpURLConnection) url.openConnection();
conection.setConnectTimeout(TIMEOUT_SOCKET);
conection.setReadTimeout(TIMEOUT_CONNECTION);
conection.addRequestProperty("Accept-Encoding", "gzip");
RedirectLocations locations = new RedirectLocations();
// here u get all header fields and properties write it in logs
conection.getHeaderFields();
conection.getRequestProperties();
// conection.getOutputStream().write(buffer);
// download the file
InputStream is = conection.getInputStream();
// This is file path were a; quiz data will get saved.
// String file_path = context.getDir(folder,Activity.MODE_PRIVATE).getAbsolutePath();
return unzip(is,save_file_path);
for redirects
link
after u get response, again u ve to look for header fields
mainly, i have loged into facebook using webview. so, i don't know which cookies for which urls are saved into CookieManager. i don't know whether it is possible or not, but i have know idea how to do it.
now, i need to get a page using Jsoup. but i need to pass some cookie also to get the page, otherwise server will return me an error pager.
i want it with Jsoup, because i need some information from the page
i have trying something like this, but all the time i am getting the error page:
Map<String, String> cookies = new HashMap<String, String>();
cookies.put(domain1, my_cookie1);
cookies.put(domain2, my_cookie2);
cookies.put(domain3, my_cookie3);
cookies.put(domain4, my_cookie4);
Document doc = Jsoup.connect(uri.toString())
.cookies(cookies)
.timeout(10000)
.get();
Log.e("title", doc.title());
my_cookie's are get from CookieManager. and they are not null, because i have printed them.
i think the problem is with cookies. or not? is there any solution. i think i am missing some cookie from CookieManager.
i need to get the page.
Edited:
or, is it possible to pass the cookimanager to Jsoup ? so, that it can take the cookie from cookiemanager directly. or, can i know which cookies are needed for getting my desire page?
i have solve the problem. first of all i was getting the right cookie all time. so what was the problem then. either i was wrong to integrate the cookie with Jsoup or Jsoup was doing something wrong. so, first i have get the page with HttpUrlConnection and then parse it with Jsoup. like this:
URL form = new URL(uri.toString());
HttpUrlConnection connection1 = (HttpURLConnection)form.openConnection();
connection1.setRequestProperty("Cookie", my_cookie);
connection1.setReadTimeout(10000);
StringBuilder whole = new StringBuilder();
BufferedReader in = new BufferedReader(
new InputStreamReader(new BufferedInputStream(connection1.getInputStream())));
String inputLine;
while ((inputLine = in.readLine()) != null)
whole.append(inputLine);
in.close();
Document doc = Jsoup.parse(whole.toString());
any advice about this code would be appreciated.
i have posted a question for htmlunit in this link: how to use htmlunit with my android project
mainly i have a link, which i have get after login (i have login through web view) this link give me a simple page. in that page there is a textarea and a submit button. and there are some javascript too (i think these javascript run, when i press the submit button). i can do it through webview, but for some reason i don't want to use webview. whene i press submit button, it deliver the value of textarea and some value of hidden field with existing cookies(which are get when i logged in through webview) Post method. i need to do this without webview. now is there any other option beside htmlunit ?? i heard about HttpClient, HttpUrlConnection. but i don't know how to use them to solve my problem, because they are totaly new to me. i think if i use these class i have to run them in a seperate thread from UI tread. one more thing, after submitting it will redirect me to another page. i don't need to do anything with this redirected page.
thank you
this is the same answer which i have given here
i have solve the problem. first of all i was getting the right cookie all time. so what was the problem then. either i was wrong to integrate the cookie with Jsoup or Jsoup was doing something wrong. so, first i have get the page with HttpUrlConnection and then parse it with Jsoup. like this:
URL form = new URL(uri.toString());
HttpUrlConnection connection1 = (HttpURLConnection)form.openConnection();
connection1.setRequestProperty("Cookie", my_cookie);
connection1.setReadTimeout(10000);
StringBuilder whole = new StringBuilder();
BufferedReader in = new BufferedReader(
new InputStreamReader(new BufferedInputStream(connection1.getInputStream())));
String inputLine;
while ((inputLine = in.readLine()) != null)
whole.append(inputLine);
in.close();
Document doc = Jsoup.parse(whole.toString());
any advice about this code would be appreciated.
In my browser, or in iOS, when I try to get the contents of a URL with encoded http authentication information in the form
http://myUser:myPassword#www.example.com/secure/area/index.html
It just works. I'm getting URLs from a web service, and I'd like to avoid trying to parse them up for their HTTP auth info if I can help it. Is there a way to do something similar in Android without actually parsing the URLs? Alternatively, what is the best way to go about that?
UPDATE:
I find that when I try to set the authentication information in an Authorization header, I get a very strange FileNotFoundException.
Here's the code I'm using:
URL url = new URL(urlString);
URLConnection connection;
String authority = url.getAuthority();
if (authority.contains("#")) {
String userPasswordString = authority.split("#")[0];
url = new URL(urlString.replace(userPasswordString + "#", ""));
connection = url.openConnection();
String encoded = new String(Base64.encode(userPasswordString.getBytes(), Base64.DEFAULT), "UTF-8");
connection.setRequestProperty("Authorization", "Basic " + encoded);
} else {
connection = url.openConnection();
}
InputStream responseStream = connection.getInputStream();
All the info seems to check out, I've verified the url is correct, the base64 string is correct, and the file is certainly on the server--I have no trouble at all opening it with Firefox, and Firebug shows all the right headers, matching what I've sent as far as I can tell. What I get though is the following error (url host changed to protect the innocent):
java.io.FileNotFoundException: http://a1b.example.com/grid/uploads/profile/avatar/user1/custom-avatar.jpg
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1061)
Any idea what this is all about?
I looked into using HttpClient, but saw that in Issue 16041 it is recommended that we prefer URLConnection.
That looks like your browser is applying some extra rules to parsing the URL. In Android you can use HTTP Client's authentication mechanism such as BASIC and DIGEST to do the same things. Which one you choose is dependent on the server you are trying to authenticate against.
Here is a good page to get you started.
Unfortunately, on Android you can't pass the user info (username/password) in that format to either java.net.URL or HttpClient and have it work like in a browser.
I'd recommend using URI (see http://download.oracle.com/javase/1.5.0/docs/api/index.html?java/net/URI.html) to do this: pass your URL to the URI constructor that takes a String and then you can extract the user info (using getUserInfo()). You can then either use HttpClient's authorization classes (see http://developer.android.com/reference/org/apache/http/auth/package-summary.html) or build the basic auth header yourself (an example is given at http://www.avajava.com/tutorials/lessons/how-do-i-connect-to-a-url-using-basic-authentication.html).