在两个不同应用程序中的Android网络视图之间共享会话(cookie)?
我有两个应用程序,有两个web视图(每个视图中有一个web视图)。为了简单地解释我的需求,在一个例子中考虑用户在他的购物车中在第一个应用程序中的第一个Web视图中添加了几个项目,然后他按下签出,这将启动第二个Web视图(在第二个应用程序中),结果:他需要看到相同的购物车(第二个Web视图也如此)。 我知道在一个应用程序中共享两个网络视图之间的cookie不是问题,它是由Android(CookieManager)在后台完成的。但是我的情况不同,我需要在两个不同的应用程序中实现相同的效果 也许我想要的是如何在不同应用程序的两个网络视图之间共享cookie/会话cookie? 注:我仅限于目标API 18 到目前为止(除了大量无用的阅读之外),我尝试的是:在两个不同应用程序中的Android网络视图之间共享会话(cookie)?,android,cookies,webview,session-cookies,Android,Cookies,Webview,Session Cookies,我有两个应用程序,有两个web视图(每个视图中有一个web视图)。为了简单地解释我的需求,在一个例子中考虑用户在他的购物车中在第一个应用程序中的第一个Web视图中添加了几个项目,然后他按下签出,这将启动第二个Web视图(在第二个应用程序中),结果:他需要看到相同的购物车(第二个Web视图也如此)。 我知道在一个应用程序中共享两个网络视图之间的cookie不是问题,它是由Android(CookieManager)在后台完成的。但是我的情况不同,我需要在两个不同的应用程序中实现相同的效果 也许我想
我可以确认我将在第二个应用程序中获得cookie,但webview似乎没有使用cookie,因为购物车仍然是空的 我希望我解释得足够好,可以得到一些反馈,我说过如果需要的话,请向我询问更多信息
我在第二个应用程序中检查了logcat,我认为这意味着无法找到购物车中的物品(getItem)(我使用了Argos.co.uk)来测试他们的购物车。换句话说,我认为cookie在加载时没有正确连接到url?!只是猜测
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
试试这个
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;
}
});
}
有一段时间没有人问我这个问题了,但我不得不做一些类似的事情(出于不同的原因) 对我来说,成功的是创建一个服务,在应用程序之间共享价值 在我的特殊情况下,它是针对被管理的移动设备的,因此我们控制设备上安装的内容。由于我们控制了一切,我创建了一个单独的应用程序安装,以提供一个独立于两个应用程序的服务,每个应用程序都有一个嵌入式网络视图 webview将在更新cookie时,通过监视webview的页面加载并在此时查询cookie,将cookie推送到服务。当应用程序前景化时,他们会从服务中加载cookie,这样他们就可以在后台和另一个应用程序处于活动状态时获取任何已设置的内容,并且这些cookie会通过CookieManager添加到网络视图中 在PlayStore上有一系列应用程序的情况下,也可以采用类似的方式,但每个应用程序中都需要有一个服务,以便其他应用程序连接并从中侦听。。。。如果有两个以上的应用程序,它可能会变得复杂-因此可能需要一些创造性的模式来处理前景化时从所有应用程序中提取,并跟踪时间戳,以找出最近保存的应用程序,从而覆盖其他应用程序 或者,如果一个应用程序始终存在,它可以是包含“服务”的“主”应用程序,并且事情将完全像我所做的那样工作
对不起,这里没有代码,我想我会分享这种方法,以防其他人需要这个想法。我从今天的工作中意识到,有一种更简单的方法可以做到这一点,所以我对答案进行了编辑,以提供我所能提供的最完整的答案 诚然,这是Xamarin.Android,但它对Android Java也应该是一样的(可能也是kotlin?): 我建议在
OnPageFinished
override中执行cookie get,但从理论上讲,您可以在任何有Android.Webkit.CookieManager.Instance
上下文的地方执行该操作。我建议在OnPageFinished()
中执行此操作的原因是,加载页面后,您应该拥有完整的cookie集
将WebView
设置为使用自定义的WebViewClient
,这将允许您覆盖OnPageFinished()
方法,从而在正确的时间获取cookie。如果您在获得cookie后不希望出现这种开销,那么您可以始终将WebViewClient
或WebView
切换到普通的未修改WebViewClient
下面是此客户端的设置(可选)
如果您不需要每次都获取cookie,那么在获取cookie之后,您就不希望使用扩展的WebViewClient
。。因为它会减慢你的应用程序。您也可以使用CookieManager
在应用程序中的任意位置获取cookie头,并将其作为参数传递给任何应用程序
您可以通过将WebView.SetWebViewClient(null)
置零,将WebViewClient
重置为库存版本。然后将其设置回未扩展版本
然后,在活动
的上下文中,执行类似的操作,这会为另一个应用程序创建一个意图
,以便做出响应,如果您的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>
然后,在接收应用程序中设置cookie后,可以使用WebView.LoadUrl(字符串url)
您还可以使用字典
重载手动附加cookie头
Dictionary<string, string> cookieHeaderDictionary = new Dictionary<string, string>();
cookieHeaderDictionary.Add("Cookie", cookieString);
LoadUrl(url, cookieHeaderDictionary);
Dictionary cookieHeaderDictionary=new Dictionary();
添加(“Cookie”,cookieString);
LoadUrl(url,cookieHeaderDictionary);
来源:
CookieSyncManager
已被弃用,据我所知,它已不再工作。
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);
}
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>
//OnCreate
MyBroadcastReceiver MyReceiver = new MyBroadcastReceiver();
//I put this OnResume() but you can experiment with different placements
RegisterReceiver(MyReceiver , new IntentFilter("first_app_packagename"));
Dictionary<string, string> cookieHeaderDictionary = new Dictionary<string, string>();
cookieHeaderDictionary.Add("Cookie", cookieString);
LoadUrl(url, cookieHeaderDictionary);