试了一个小Demo,从WebApp上直接调起Android Native App,包括应用已安装和未安装的情况,还是蛮有意思,记录点儿东西:
第一,在AndroidManifest.xml中对<activity />标签增加<intent-filter />,如下:
<!--用这个Activity专门处理本App调起的情况--> <activity android:name="com.baidufe.shemedemo.SchemeActivity" android:label="@string/app_name"> <!--要想在别的App上能成功调起App,必须添加intent过滤器--> <intent-filter> <!--协议部分,随便设置--> <data android:scheme="baidufe"/> <!--下面这几行也必须得设置--> <category android:name="android.intent.category.DEFAULT"/> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.BROWSABLE"/> </intent-filter> </activity>
第二,在SchemeActivity中接收并处理Uri请求,实现跳转到不同的Native App页面,获取Uri可以在Activity中通过getIntent().getData()实现,Demo:
// 尝试获取WebApp页面上过来的URL Uri uri = getIntent().getData(); if (uri != null) { StringBuffer sb = new StringBuffer(); // 完整的url信息 sb.append("url: " + uri.toString()); // scheme部分 sb.append("\nscheme: " + uri.getScheme()); // host部分 sb.append("\nhost: " + uri.getHost()); // 访问路劲 sb.append("\npath: "); List<String> pathSegments = uri.getPathSegments(); for (int i = 0; pathSegments != null && i < pathSegments.size(); i++) { sb.append("/" + pathSegments.get(i)); } // Query部分 sb.append("\nquery: ?" + uri.getQuery()); tv.setText(sb.toString()); }
第三,在WebApp页面上,通过如下方式使用:
<!-- 注意这里的href格式 -- > <a href="baidufe://schemedemo/get/info?id=10000">open baidufe android app</a>
上面的链接看起来和平时看到的链接是不一样的,baidufe:// 这个协议是被注册到android app中的,整个格式都是我们自定义的,当然,也可以改成任意的样子,比如:com.baidufe://a/b/c 。只不过,这个Uri的格式需要提前定义好,要不然在SchemeActivity中无法匹配上。在SchemeActivity中,可以获取到这个Uri,并分段解析,进而启动不同的Activity,实现从WebApp中跳转到Native App的不同页面。
当然,还有一种方法,是通过注册service,并通过ServerSocketChannel去bind一个端口,比如9999,启动该service后,即可在WebApp中通过 http://127.0.0.1:9999 进行访问,当然,根据service的不同实现,可以在后面加一定的path和query,比如:http://127.0.0.1:9999/dealIntent?intent=....&callback=.... 。这种方式比scheme更灵活,但缺点也是很明显的:service长期处于启动状态,耗电是必须要考虑的。