在两个不同的应用程序中的Android Webview之间共享会话(cookie)?

时间:2015-12-18 15:59:35

标签: android cookies webview session-cookies

我有两个带有两个Web视图的应用程序(每个视图中都有一个Web视图)。通过一个例子简单地解释我的要求,考虑用户在第一个应用程序的第一个Web视图中添加购物车中的几个项目,然后按下结帐,这将启动第二个Web视图(在第二个应用程序中),结果:他需要看到相同的购物车(在第二个网络视图中)。

我知道在一个应用程序中共享两个webview之间的cookie不是问题,它是由Android( CookieManager )在后台完成的,但是我的情况不同,我需要在两个实现相同的不同的应用程序。

也许我正在寻找的是如何在不同应用中的两个网页浏览之间共享Cookie /会话Cookie?

注意:我仅限于目标API 18

到目前为止我尝试过的(除了大量无用的阅读之外)是:

  1. 从第一个webview获取URL的cookie并发送给它 意图进行第二次APP活动
  2.     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. 在第二个应用webview中设置Cookie
    2. 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;
      }
      });
      }
      

      我可以确认我会在第二个应用程序中获取cookie,但似乎webview没有使用cookie,因为购物车仍然是空的。

      我希望我解释得足够好以获得一些反馈,如果有需要请告诉我更多信息

      我在第二个应用程序中检查了logcat,我认为这意味着无法找到小车中的物品(getItem)(我使用Argos.co.uk)来测试他们的购物手推车另一个词我认为cookie没有附加到网址正确加载?!只是在猜...

      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
      

3 个答案:

答案 0 :(得分:0)

试试这个......

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;
    }
});
}

答案 1 :(得分:0)

问了已经有一段时间了,但是我只是不得不做类似的事情(由于不同的原因)...

对我有用的是创建一个服务,以在应用之间共享值。

在我的特定情况下,它是针对受管理的移动设备的-因此我们控制了设备上安装的内容。由于我们控制了一切,因此我创建了一个单独的应用安装,以提供独立于两个均具有嵌入式Webview的应用的服务。

在更新cookie时,webview会通过监视webview的页面加载并在那时查询cookie来将cookie推送到服务。他们会在应用程序前台运行时从服务中加载Cookie,这样他们就可以获取在后台运行且其他应用程序处于活动状态时设置的所有内容,并且这些Cookie通过CookieManager添加到了Webview中。

在PlayStore上有一系列应用程序的情况下,可以类似地完成此操作,但是每个应用程序中都需要有一个服务,以便另一个应用程序可以连接到该应用程序并从中进行侦听...。如果有2个以上的应用程序,则可能会变得很复杂-因此可能需要一些创造性的模式来处理在前景出现时从所有应用程序中提取的内容,并跟踪时间戳以找出最近保存的应用程序,从而覆盖其他应用程序。 ..

或者,如果始终有一个应用程序存在,那么它可以是包含“服务”的“主”应用程序,一切将按照我所做的工作正常进行。

对不起,这里没有代码,以防万一其他人需要这个想法,我会分享这种方法。

答案 2 :(得分:0)

我从今天的工作中意识到,有一种更简单的方法可以完成此操作,因此答案已经过编辑,可以提供最完整的答案。

Xamarin.Android,但是它对于Android Java应该也可以工作(也许也是kotlin吗?):

我建议将Cookie改写为OnPageFinished,但从理论上讲,您可以在有Android.Webkit.CookieManager.Instance上下文的任何地方进行操作。我建议在OnPageFinished()中这样做的原因是,页面加载后应该具有完整个cookie。

WebView设置为使用自定义的WebViewClient,这样您就可以覆盖OnPageFinished()方法,从而在正确的时间获取cookie。如果您不希望在获得Cookie后出现这种开销,那么可以随时将WebViewClientWebView切换为未经修改的香草WebViewClient

此处设置了此客户端(可选)

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

这是从中获取cookie

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);
            }

        }

如果您不需要每次都获取Cookie,则在获取Cookie之后就不希望使用扩展WebViewClient了,因为它会减慢您的应用程序的速度。您也可以使用CookieManager在应用程序中的任何位置获取cookie标头,并将其作为参数传递给任何

您可以通过将WebViewClient设为空,将WebView.SetWebViewClient(null)重置为备用股票,然后将其设置回未扩展的版本。

然后,在Activity的上下文中,执行类似的操作,从而为另一个应用程序创建一个Intent以便响应,并在此处注意是否cookie中包含安全令牌。

应用发送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);
}

在接收Cookie的应用中,扩展广播接收器:

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"));
    }
}

清单(接收应用程序),设置意图过滤器:

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

并在您的接收应用的Activity

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

然后您可以在接收应用中WebView.LoadUrl(string url)后使用SetCookie

您还可以使用Dictionary<string, string>重载手动附加cookie标头

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

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