1

I have two Applications with two web-views (a web-view in each). to simply explain my requirement with an example consider a user adds few items in his shopping trolley in first web-view in first app and then he press checkout and this will launched second web-view (which is in second app), result : he needs to see same shopping cart (in second web-view too).

I know sharing cookies between two webviews in a single app is not a problem and it is done in background by Android (CookieManager) however my case is different, I need to achieve the same in two different App.

Perhaps what I am looking for is how to share cookies/ session cookies between two webviews in different apps?

Note: I am restricted to targeted API 18

What I tried so far (apart of lots of useless reading) is :

  1. getting cookie of the URL from the first webview and send it through intent to second APP's activity

    mWebView.setWebChromeClient(new WebChromeClient() {
    });
    mWebView.loadUrl(getPreferedURL().toString());
    WebSettings settings = mWebView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setAppCacheEnabled(true);
    mWebView.setWebViewClient(new WebViewClient() {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (!url.contains("openCheckoutPage")) {
                return false;
            } else {
                mCookie = CookieManager.getInstance().getCookieurl);
                Intent fullScreenIntent = new Intent("com.bastami1982.webview.app.WebviewPanel_ACTION");
                fullScreenIntent.putExtra("mUrl", mUrl);
                fullScreenIntent.putExtra("mCookie", mCookie);
                startActivity(fullScreenIntent);
                return true;
            }
        }
    });
  1. set the cookie in second app webview

private void loadFullWebview() { 
mLink = getIntent().getStringExtra("mUrl");
mLinkCookie = getIntent().getStringExtra("mCookie");
mFullScreenWebView = (WebView) findViewById(R.id.webView);
mFullScreenWebView.setWebChromeClient(new WebChromeClient() {
});
WebSettings settings = mFullScreenWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAppCacheEnabled(true);
if (mLinkCookie!=null) {
mCoockieManager.setAcceptCookie(true);
mCoockieManager.setCookie(mLink, mLinkCookie);
mCoockieManager.acceptCookie();
CookieSyncManager.getInstance().sync();
}
mFullScreenWebView.loadUrl(mLink);
mFullScreenWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
}

I can confirm that I will get the cookie in second app but it seems webview is not using the cookie because the shopping cart is still empty.

I hope I explained it good enough to have some feedback , having said that please ask me for more info if it is needed


I checked the logcat in second App and I think this means that items in trolley can not be find (getItem) (I used Argos.co.uk) to test their shopping Trolley in another word I think cookie is not attached to the url correctly at loading ?! just guessing...

12-18 16:18:11.754 14675-14675 I/Web Console: Error while sending custom tracking data at https://d1af033869koo7.cloudfront.net/psp/argos-v1-001/default/20151216103020/pxfwk.gz.js:7
12-18 16:18:11.904 14675-14675 E/Web Console: Uncaught TypeError: Cannot call method 'getItem' of null at https://argospsp.px.247inc.net/pspxd.html#parentdomain=https://www.argos.co.uk&clientkey=argos-v1-001&version=20151216103020&pspv=default&n=1&caller=refloaded&l=1000&s=cookie:5
bastami82
  • 5,955
  • 7
  • 33
  • 44

3 Answers3

0

Try this...

private void loadFullWebview() { 
mLink = getIntent().getStringExtra("mUrl");
mLinkCookie = getIntent().getStringExtra("mCookie");
mFullScreenWebView = (WebView) findViewById(R.id.webView);
WebSettings settings = mFullScreenWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAppCacheEnabled(true);
if (mLinkCookie!=null) {
    mCoockieManager.removeSessionCookie();
    CookieSyncManager.createInstance(this);
    mCoockieManager.acceptThirdPartyCookies(mFullScreenWebView,true);
    mCoockieManager.setAcceptCookie(true);
    mCoockieManager.setCookie(mLink, mLinkCookie);
    CookieSyncManager.getInstance().sync();
}
mFullScreenWebView.loadUrl(mLink);
mFullScreenWebView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        return false;
    }
});
}
Deepak
  • 756
  • 4
  • 10
0

It's been a while since this was asked, but I just had to do something similar (for different reasons)...

What worked for me was to create a service to share the values between the apps.

In my particular case, it was for mobile devices that were managed - so we controlled what is installed on the devices. Since we controlled things, I created a separate app install to have a service which was independent from both of the apps that each had an embedded webview.

The webviews would push cookies to the service when they were updated via monitoring the webview's page loads and querying for cookies at that point. They would load cookies up from the service when the app was foregrounded so they would get anything that had been set while they were backgrounded and the other app was active - and those cookies were added to the webview via the CookieManager.

In the case where there is a family of apps on the PlayStore, it could be done similarly, but there would need to be a service in each app for the other app to connect to and listen from.... If there are more than 2 apps, it could get kind of complex - so might need some creative patterns to handle pulling from all the apps when foregrounded, and keeping track of timestamps to sort out which ones were more recently saved so they overwrite the others....

Or, if one app will always be present, it can be the "main" app that contains the "service", and things will work exactly as what I've done.

Sorry no code here, figured I'd share the approach in case anyone else needs the idea.

m0bl
  • 562
  • 5
  • 9
0

I realized from working today that there's an easier way to do this, so answer has been edited to give the most complete answer I could.

Granted, this is Xamarin.Android, but it should work the same for Android Java (maybe kotlin too?):

I recommend doing the cookie getting in OnPageFinished override, but you could theoretically do it anywhere you have an Android.Webkit.CookieManager.Instance context. The reason I recommmend doing it in OnPageFinished() is because you should have the full set of cookies after your page loads.

Set your WebView to use a customized WebViewClient as such, which will allow you to override the OnPageFinished() method, thus getting the cookies at just the right time. If you don't want this overhead after you've got the cookies then you can always switch the WebViewClient or WebView to a vanilla unmodified WebViewClient.

Here's setting this client (optional)

FragmentContainerLayout = inflater.Inflate(Resource.Layout.Tab0FragLayout, container, false); }
Wv = FragmentContainerLayout.FindViewById<WebView>(Resource.Id.webView1);
Wv.SetWebViewClient(new LoginWebViewClient());

and here's getting the cookie from

APP SENDING COOKIE:

        public class LoginWebViewClient : WebViewClient
        {
            public override void OnPageFinished(WebView view, string url)
            {
                RunPageCommands(view);
                base.OnPageFinished(view, url);
            }

            public static void RunPageCommands(WebView w)
            {
                try
                {
                    //replace this with yourDomain
                    string exampleDomain = "https://www." + "example.com"+ @"/"; //or .net or .tv etc
                    // get the cookie header in context
                    string cookieHeader = Android.Webkit.CookieManager.Instance.GetCookie(exampleDomain);


                }
                catch { return; /*cookie getting failed, nothing to do*/ }
                ShareCookieWithAnotherApp(cookieHeader, exampleDomain);
            }

        }

if you don't need to get the cookie every time then you would not want to use an extended WebViewClient after you've got the cookie .. as it will slow down your app. You can alternatively just get the cookie header anywhere in the app with the CookieManager and pass it as an argument to any

You can reset the WebViewClient to the stock one by nulling it out WebView.SetWebViewClient(null) then set it back to the unextended version

then, in the context of an Activity, do something like this, which creates an Intent for another app to respond, and be careful here if your cookie has security tokens in it.

App SENDING cookie:

public void ShareCookieWithAnotherApp(string cookie, string domain){
        Intent intent = new Intent();
        intent.SetClassName("com.appstore", "com.appstore.MyBroadcastReceiver");
        intent.SetAction("com.appstore.MyBroadcastReceiver");
        intent.PutExtra("CookieSyncExtra", cookie);
        intent.PutExtra("CookieDomainExtra", domain);
        SendBroadcast(intent);
}

in the app receiving cookie, extend broadcast receiver:

public class MyBroadcastReceiver : BroadcastReceiver {
    
    //this fires when it receives the broadcast from the sending app
    public override void OnReceive(Context context, Intent intent) {
        // set the CM to accept cookies
        CookieManager.Instance.SetAcceptCookie(true);   
          
        //and set the cookie from your extras
CookieManager.Instance.SetCookie(intent.GetStringExtra("CookieDomainExtra"), intent.GetStringExtra("CookieSyncExtra"));
    }
}

Manifest (receiving app), set the intent-filter :

        <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="first_app_packagename" />
            </intent-filter>
        </receiver>

and in your Activity of the receiving app:

      //OnCreate 
      MyBroadcastReceiver MyReceiver = new MyBroadcastReceiver();
      //I put this OnResume() but you can experiment with different placements
      RegisterReceiver(MyReceiver , new IntentFilter("first_app_packagename"));

then you can use the WebView.LoadUrl(string url) after you've SetCookie in the receiving app

you can also attach the cookie header manually using the Dictionary<string, string> overload

Dictionary<string, string> cookieHeaderDictionary = new Dictionary<string, string>();
cookieHeaderDictionary.Add("Cookie", cookieString);
LoadUrl(url, cookieHeaderDictionary);

source: How to send data between one application to other application in android?

hexagod
  • 449
  • 3
  • 15