我有一种情况,我希望将一些数据从移动网站传递到原生Android应用程序。一个复杂的问题是,在正常情况下,加载移动网站时可能不会安装原生Android应用程序。
这是一个例子:
我是ExampleApp的用户,我想与您分享来自ExampleApp的特定数据,而您从未安装过ExampleApp。
我发送了一封电子邮件,其中包含指向移动网页的链接,该网页知道您打开链接时要查看的数据。但是,由于数据仅在本机应用程序中可用,而不是移动网络,因此您将进入一个页面,要求您转到Android Market并安装ExampleApp。
您安装了ExampleApp,理想情况下,您将直接访问我与您共享的数据。
最大的问题是查看移动网页和安装ExampleApp之间的脱节。
我已经考虑了几个解决方案,但都没有成功(也就是说,我可能只是错误地实现它们):
- 在我们的域上设置一个cookie,其中包括加载移动网页时的数据。然后,当打开ExampleApp时,启动WebView以请求同一域上的页面并检查cookie的值。使用它来确定要在ExampleApp中显示哪些数据。
- 使用JavaScript localStorage存储对该数据的引用,并使用WebView获取该域上的页面,并从ExampleApp中请求localStorage的内容。
在这两种情况下,似乎WebView和浏览器都是相互远离的沙箱,因此您无法获得两者之间的cookies / localStorage。
有没有其他方法可以“留下crumbtrail”或设置一条消息,以后安装的应用程序可以从浏览器访问?
编辑:鉴于一些回复,我应该提到我只希望你点击链接一次,不必点击一次,安装应用程序,然后再次点击打开应用程序到正确的地方。
解决方案实际上非常简单,我有点惊讶,没有人能够提出它超过一年。所以这里是:
基本思想是使用cookie来存储信息。数据流如下:
打开网页 - >设置cookie - >重定向到市场 - >安装应用程序 - >使用网页启动浏览器 - >读取cookie - >使用cookie数据启动自定义意图 - >捕获意图并读取cookie数据
用户访问网页(例如,通过扫描QR标签)。网页的网址包含您要传递的数据的引用,或者保存数据本身。该网站将数据设置为cookie并重定向到Android市场(http://market.android.com/details?id=com.yourapp)。只要您的应用启动,您就会打开浏览器并再次加载相同的网页。但是,这次它检测到cookie已经设置并重定向到自定义URL方案,例如:example://example.com/installed?id = DATA,而不是市场。使用意图过滤器,您可以启动活动并从意图中提取信息。
这是相关的活动代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if(intent == null || intent.getData() == null || !"example".equals(intent.getData().getScheme())) {
String url = "http://example.com/yourApp/index.php";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
finish();
return;
}else {
Uri uri = intent.getData();
if("example".equals(uri.getScheme())) {
id = uri.getQueryParameter("id");
}
}
... initialise your activity ...
}
一个简单的PHP文件(网站),便于演示:
<?php
$value = "123";
if(!isset($_COOKIE["TestCookie"])) {
setcookie("TestCookie", $value, time()+3600); /* expire in 1 hour */
header("Location: http://market.android.com/details?id=com.yourapp");
exit;
}else {
header("Location: example://example.com/installed?id=".$_COOKIE["TestCookie"]);
exit;
}
?>
并且意图过滤器:
<!-- Handle URLs like loyalty://example.com/merchant/123 -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="example" android:host="example.com" />
</intent-filter>
顺便说一句,我已经决定了 博客 关于这个问题。
有没有其他方法可以“留下crumbtrail”或设置一条消息,以后安装的应用程序可以从浏览器访问?
我认为有一个更简单的解决方案,一种条形码扫描仪所采用的解决方案。
步骤1:创建一个包含所需信息的漂亮RESTful URL。通过RESTful,我的意思是没有 ?
不,不 #
,没有那个废话。如果这是一个不同的域名,这将是一个更简单的,但这可能只是你现有的域名。出于本答案的目的,我将假设此URL看起来像 http://android.exampleapp.com/our/custom/data/goes/in/here/somewhere
。
步骤2:对于可以按照步骤#1的模式创建的所有URL(任何内容) http://android.exampleapp.com
),您的Web服务器应该提供一个页面说“嘿!您没有安装ExampleApp!如果您在此处单击此链接,它将带您到Android Market,在那里您可以安装ExampleApp!然后,尝试单击链接这会带你到这个页面,它会启动ExampleApp并给你......嗯......所有这些好的数据“。
步骤3:在ExampleApp中实现具有的活动 <intent-filter>
随着 VIEW
行动, BROWSEABLE
类别,和 <data>
标识您的方案和域的元素(如果需要,还有基本路径,如果所有这些链接都相同)。
用户看到的内容,如果他们没有安装ExampleApp并单击链接,则是来自步骤#2的Web页面,他们可以从中安装ExampleApp。
用户看到的内容,如果他们确实安装了ExampleApp并单击链接,则是您的活动,可以通过该URL获取URL getIntent().getData()
并做一些有用的事情。
UPDATE
在评论中,你写道:
移动网页=>存储数据 => 用户安装应用程序 => 用户打开app => app检索数据=> app直接打开检索到的内容
恕我直言,你对用户将做什么做了太多的假设。我以粗体显示的箭头之间可能有数天,数周或数月的延迟。
如果你打算自己发布它(例如,你的Web服务器之外),你总是可以选择用它们里面的数据“烧”他们自己的APK,但是你必须自己处理管理更新。
或者,如果您使用的是基于帐户的系统,请让他们在您的网站上创建一个帐户,然后再将其发送到Android电子市场。将数据存储在该帐户下,当他们从应用程序连接回该帐户时,您可以将数据与应用匹配。
使用GET参数: http://exampleapps.com?token=mK7Fyt5 想想YouTube应用的工作方式。您已被发送到视频的链接。如果您没有YouTube应用,则会看到移动网站(在您的情况下可能是安装链接)。如果这样做,系统会询问您是否使用本机应用打开YouTube链接,并且本机应用程序会传递调用它的URL,从中可以解析要显示的视频的参数。
使用以下intent过滤器:
<intent-filter>
<data android:scheme="http" android:host="exampleapps.com"/>
<action android:name="android.intent.action.VIEW" />
</intent-filter>