Android Persistent Cookie Store with HTTPUrlConnection - android

I searched a lot now for the persistence of Cookies but cant find a good solution.
I use HTTPUrlConnection to authenticate against a server and I get Cookies back. I retrieve them in CookieManager and can load them into a new connection. Now I want to persistent that Cookies, perhaps the whole Cookiemanager Object. I found a solution, that you can persist the Cookies with specifying a CookieStore by creating the CookieManager.
I found only old solutions (2-3 years) that say you have to build your own persistent CookieStore, since a persistent CookieStore is not implemented in the SDK? Is this up to date? Is there already a persistent CookieStore implemented in the SDK or does I have to persist the Cookies by myself with SharedPreferences? Or does anybody has a better solution to persist Cookies nowadays?
Best Regards,

This seems to be answered in some other palces, I didn't try it but you can get a detailed explain in this link:
http://blog.winfieldpeterson.com/2013/01/17/cookies-in-hybrid-android-apps/
public class YourApplication extends Application {
public void onCreate() {
super.onCreate();
//Setup Cookie Manager and Persistence to disk
CookieSyncManager.createInstance(this);
CookieManager.getInstance().setAcceptCookie(true);
}
}
public class MainActivity extends BaseActivity {
public void onResume() {
CookieSyncManager.getInstance().stopSync();
}
public void onPause() {
CookieSyncManager.getInstance().sync();
}
}
API21 deprecates CookieSyncManager, now to ensure that cookies are written to disk use:
CookieManager.flush()

Related

android WebView cookies expires when exit app

As the CookieSyncManager.getInstance().sync(); is deprecated Itried to maintain cookies forever in my application using new command
flush() :
webview.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().acceptCookie();
CookieManager.getInstance().acceptThirdPartyCookies(webview);
CookieManager.getInstance().flush();
}
// and more settings for webview
}
But every time I open the app it seems that previous cookies were expired. Do those options help preserving cookies? And Should I put them in onPageFinished?
Besides I have to say that the cookies are working fine on the target website and are set to live for 100 days. Also minSdkVersion is 21 and targetSdkVersion is 29.
Using PersistentCookieJar — persistent and good for encapsulating the Cookies within the App itself. please checkthis
every time APP plan to launch Webview, the cookies will need to be copied from the PersistentCookieJar to the CookieManager.

Android testing. Mocking HttpUrlConnection(partially)

I have to create a test system that intercept all HTTP requests but should handle only few, after some researches I found this article that shows how to mock HttpUrlConnection but I have to adapt, I want to use this only for requests that is part of my test, the others should go through internet as usualy, my try was to return different HttpUrlConnection objects that depends on url and obviously didn't work.
public class MockURLStreamHandler extends URLStreamHandler implements URLStreamHandlerFactory
{
..............................
// *** URLStreamHandler
#Override
protected URLConnection openConnection(URL u) throws IOException {
mConnection = new MockHttpURLConnection(u);
if(u.toString().equals(myTestUrl))
{
return mConnection;
}
else
{
//this doesn't work
return new HttpUrlConnection(u){..}
}
}
...............................
}
Any ideas ? after what I should looking for?
Thanks in advance.
Take a look at MockWebServer
This library makes it easy to test that your app Does The Right Thing
when it makes HTTP and HTTPS calls. It lets you specify which
responses to return and then verify that requests were made as
expected.
Because it exercises your full HTTP stack, you can be confident that
you're testing everything. You can even copy & paste HTTP responses
from your real web server to create representative test cases. Or test
that your code survives in awkward-to-reproduce situations like 500
errors or slow-loading responses.

Robotium Test to Extract Cookies from WebView

My Sign Up Process produces cookies in a WebView, not in native code. All my tests depend on the cookies retrieved from the Webview so I need a way to extract data from a webview inside a Robotium test. How can this be done? Here is my WebView fragment:
public class MyWebViewFragment extends Fragment {
private CookieManager cookieManager;
#ViewById
WebView myWebView;
#AfterViews
void theAfterViews() {
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.getSettings().setDomStorageEnabled(true);
CookieSyncManager.createInstance(getActivity());
cookieManager = CookieManager.getInstance();
myWebView.loadUrl(theURL);
myWebView.setWebViewClient(new WebViewClient()
{
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if ((url != null) && (url.equals(theURL)))
{
String theCookies = cookieManager.getCookie(url);
// ######## I need to pull these Cookies out here in the Robotium test. How do I use Solo etc to do this?
}
}
}
}
I need to know how to write a Robotium test that will at the right point pull out the values of the Cookies and save it for the rest of the tests to use. I need to get thiw working or none of my other tests will run. Thanks
The simple answer as i think you may know having seen your other questions is to get hold of the fragment and then ask the fragment for the value. Potentially you might consider mocking this functionality out for your tests or allow your tests a method to be able to set the cookies for itself etc (not sure if this is feasible for your case or not.)

How to clear logon credentials from WebView?

I want to clear application data like i can do it from settings. I need to clear login information in WebView when i am login to facebook or twitter, because when i log on once for each of the following uses the same data automatically
I try this:
http://www.hrupin.com/2011/11/how-to-clear-user-data-in-your-android-application-programmatically
didn't work, login information are still in browser
I try reset app:
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
also
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
view.clearCache(true);
if(b){
Log.d("WEBVIEW", "onFinisghed b true");
Map<String, String> noCacheHeaders = new HashMap<String, String>(2);
noCacheHeaders.put("Pragma", "no-cache");
noCacheHeaders.put("Cache-Control", "no-cache");
view.loadUrl(url, noCacheHeaders);
b = false;
}...
Most of the entries refers to the first method which is described in the link, but it does not work in my case, any ideas?
Try clearing the browser cookies. Logon credentials are often stored in browser cookies, which you can delete by a call to
CookieManager.getInstance().removeAllCookie();
Update:
CookieManager.getInstance().removeAllCookie() was deprecated in Android SDK 21 (Lollipop), and was replaced by CookieManager.getInstance().removeAllCookies(ValueCallback callback). As of November 2018, removeAllCookie() stills works as specified. Also, in the newer method removeAllCookies(ValueCallback callback), the callback function can be null if you don't want to be notified about removed cookies. Thus, it's safe to use
CookieManager.getInstance().removeAllCookies(null)
as a direct replacement for CookieManager.getInstance().removeAllCookie() when targeting devices after Android SDK 21.
CookieManager documentation is here.
How about WebView.clearCache(boolean)?
CookieManager.getInstance().removeAllCookie();
above method will resolved problem but This method was deprecated in API level 21 so use removeAllCookies(ValueCallback) instead.
This method is asynchronous. If a ValueCallback is provided, onReceiveValue() will be called on the current thread's Looper once the operation is complete. The value provided to the callback indicates whether any cookies were removed. You can pass null as the callback if you don't need to know when the operation completes or whether any cookies were removed, and in this case it is safe to call the method from a thread without a Looper.
ValueCallback: a callback which is executed when the cookies have been removed

Unable to connect to Tridion Core Service from an Android client

I am developing an Android app for connecting to Tridion 2011 SP1 Core Service.
So far I have created Android WS Stubs from the core service wsdl using wsclient.
Imported those stubs, which allow access to all the core service methods.
I can now authenticate to Tridion via the Android application but as soon as I try to perform even the most basic of web service calls, such as getApiVersion(), I get the error:
ReflectionHelper*java.lang.NoSuchFieldException: GetApiVersionResult.
I was wondering has anyone else managed to create a java android app that communicates with the Core Service?
Interestingly enough, if I run the code as a java application, using wsimport stubs everything works a treat.
Any help appreciated. For reference here is a code snippet:
To connect to Tridion:
class TridionConnect extends AsyncTask<String, Integer, String> {
// Called to initiate the background activity
#Override
protected String doInBackground(String... statuses) {
try {
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
});
url = new URL("http://tridion-server/webservices/CoreService2011.svc?wsdl");
System.out.println(String.format("Get Service"));
service = new CoreService2011();
System.out.println(String.format("Get Client"));
client = service.getBasicHttp();
return "Authenticated To Tridion";
} catch (Exception e) {
Log.e("Authentication failure", e.toString());
e.printStackTrace();
return "Failed to authenticate";
}
}
// Called when there's a status to be updated
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// Not used in this case
}
// Called once the background activity has completed
#Override
protected void onPostExecute(String result) { //
Toast.makeText(FullscreenActivity.this, result, Toast.LENGTH_LONG).show();
area.setText("Authenticated to Tridion OK");
}
}
To get the ApiVersion
client.getApiVersion();
UserData currentUser = client.getCurrentUser();
System.out.println(String.format("'%s' %s", currentUser.getTitle(), currentUser.getId()));
Frank,
It is not possible for a couple of reasons.
If you use wsimport to create the coreservice proxy it will use the javax library, which exists in the JRE. However Dalvik implements only a subset of the javax library which means this approach is impossible in the Android environment.
I then looked at Ksoap2 tools for creating the proxy. This seemed to work OK, in as much as it did create a proxy, however it did not match the coreservice so I was unable to authenticate. I didn't get any further with this approach beyond examining the JRE proxy v Ksoap2 proxy. They were quite different.
At this point I took a step back, had a cup of tea and re-engineered the approach.
I created a c# REST service to sit between the android app and the core service.
This approach seemed a bit complex, but it offers lots of advantages. Lots of the spade work can be done in the REST service, which will be much quicker than similar code on a tablet or phone.
Secondly the REST service sits on the same server as the CMS/CoreService so the comms is quicker and you can make the REST requests from the android app much lighter.
I have got the application to the point where you can authenticate to Tridion, select a publication, and components that is then rendered in a dynamic layout ready for update/save/publish.
The one big downside of this approach is that the REST service 'should' be stateless so superficially you have to authenticate to the coreservice for every request. Of course I don't do that, but you have to come up with some alternative approach Oauth, shared secret etc.
In initial tests this approach has seemed to be fairly slick on an android device.

Categories

Resources