这个功能其实做了有一段时间了,一直想写点东西,又总是写一半又放下。趁着年前的时间还是多多少少的总结一点把。
最初做手机浏览器起调native APP的指定页面的功能,这个功能也查了很多的资料,但是估计是搜索关键字不对,当时也没查到完整的解决方案,甚至这个写的挺完善的文章 都没看到,导致我这篇文章跟他的雷同的好多。
跟他测试的一样,uc打不开,自己测试的几个QQ浏览器,手机自带的浏览器是可以的。
具体参考如下,H5部分
androidjumpurl='com.packagename.XXX://?params={"type":"'+type+'","value":"'+value+'"}';
var ifr = document.createElement('iframe');
ifr.src = androidjumpurl;
ifr.style.display = 'none';
document.body.appendChild(ifr);
window.setTimeout(function(){
showdownload();document.body.removeChild(ifr);
},2000)
H5这边比较简单,设置一个 androidjumpurl(名字随意)的链接,前面的是你的包名 ,pamras字段里写一段json数据,起调本地页面之后的可以带过去数据,当然也可以传空。2S后,网页弹出下载框,可以调用下载的方法进行下载app(成功调起app的话,就会进入app)。
之后,就是安卓部分的设置了,首先是需要app的入口,这里我用的是mainactivity,因为考虑到启动指定页面后需要有返回的操作,当然也自己随意写
<mainactivity>
<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:pathPrefix="/"
android:scheme="com.packagename.XXX"/>
</mainactivity>
之后是在activity中接收这个数据,然后拿到数据后解析json,之后再根据json的类型进行跳转。接收的activity就不用再贴出来了吧,就是个intent跳转。
Uri uridata = getIntent().getData();
if(uridata !=null&& !TextUtils.isEmpty(uridata.toString())) {
String id = uridata.getQueryParameter("type");
if(!TextUtils.isEmpty("id")) {
try{
JSONObject jsob =newJSONObject(id);
String value = jsob.optString("value");
if(!TextUtils.isEmpty("type")) {
if(value.equals("activity1")) {
intent2Activyty(1,value);//传递参数进去
}else if(des.equals("activity1")) {
intent2Activyty(2,value);
}else{
return;
}
}
}
}catch(JSONException e) {
e.printStackTrace();
return;
}
}
}
}
之后是关于本地webview中h5和native联动的一些简单实现。其事就是webview的H5启动本地页面
webView = (WebView) findViewById(R.id.mywebview);
//设置WebView属性,能够执行Javascript脚本
webView.getSettings().setJavaScriptEnabled(true);
// 其作用的代码如下
//加载需要显示的网页
webView.loadUrl(url);
//设置浏览器
web_push.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("http://www.XXX.com/open?")) {
// 比如链接是一个 http://www.XXX.com/open?id=1&key=1
//之后有了链接操作就简单了,比如直接替换分割拿到数据
String replace = url.replace("http://www.XXX.com/open?", "");
String[] split= replace.split("=");
//根据这个split[0] split[2]可以进行相关操作了
////////////////////特别的,提供一个webview使用整个APP网络访问持有的cookies的方式
setcookies(this,url);
////////////////////
return true;
} else {
MyApp.setWebViewCookie(H5WebviewActivity.this, url);
}
return super.shouldOverrideUrlLoading(view, url);
}
});
由于项目要求网络访问都持有同样的cookies访问,我项目使用的是okhttp+glide 所以就采用了glide走okhttp方式来使用同一套cookies。
可以参考 compile 'com.github.franmontiel:PersistentCookieJar:v0.9.3' 来使用
1.MyApp extends Appcation
2.getCookieJar() 即获得整个app使用的cookies
public static void setWebViewCookie(Context context, String url) {
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
// cookieManager.removeSessionCookie();// 移除
cookieManager.removeAllCookie();
List<Cookie> cookies = MyApp.getApp().getCookieJar().loadForRequest(HttpUrl.parse(url));
StringBuffer sb = new StringBuffer();
for (Cookie cookie : cookies) {
String cookieName = cookie.name();
String cookieValue = cookie.value();
if (!TextUtils.isEmpty(cookieName)
&& !TextUtils.isEmpty(cookieValue)) {
sb.append(cookieName + "=");
sb.append(cookieValue + ";");
}
}
String[] cookie = sb.toString().split(";");
for (int i = 0; i < cookie.length; i++) {
cookieManager.setCookie(url, cookie[i]);// cookies是在HttpClient中获得的cookie
}
CookieSyncManager.getInstance().sync();
}
基本上算是想到哪写哪,本来只是想写浏览器启动本地APP的,然后想起webview相关,加上牵扯到cookies的一些东西,就一并写上。其实也不算难,都是些很基础的东西。只是当时项目用到时候找了好久的也没找到的东西,作为一个记录放在这里吧,省的以后再用找不到。也欢迎拍砖或者提供更好的思路。