了解Android微信里的WebView是如何实现分享的功能
来源:互联网 发布:阿里云人工在线客服 编辑:程序博客网 时间:2024/06/03 13:12
了解Android微信里的WebView是如何实现分享的功能
本文是通过一些技巧,使用javascript
与android webview
之间的通讯,去获得微信公众号文章的分享标题与图片链接等信息。目的是模仿微信的浏览器是如何获取内容去进行分享,从而将这种技术引入到自己的项目中。而微信浏览器里,读取分享内容有两种方式,一种是通过读取网页的标题与首张图片链接作为分享的内容;另一种是公众号后台生成的文章与授权第三方网站使用js-sdk的去自定义分享内容。
先对比两种分享的效果
区别还是挺大的,要做更好的用户体验,就需要有耐心去突破。
普通网页抓取的分享内容
换取标题,这个比较简单,webview.getTitle()
而读取首张图片地址,简单方式可以在WebViewClient
里覆写onLoadResource
方法,然后判断是否为图片的链接,如下
@Overridepublic void onLoadResource(WebView view, String url) { super.onLoadResource(view, url); //读取加载中的资源里的图片 if(cacheFirstLoadImageUrl == null && !TextUtils.isEmpty(url)) { if(url.contains(".png") || url.contains(".jpg")) { cacheFirstLoadImageUrl = url; } }}
当然,如果网页没有图片,则可以用网页的favicon,webview.getFavicon()
抓取微信公众号文章的分享内容
在微信公众号的后台,有一个素材管理,可以通过它里面的文章编辑器来编写或修改文章,然后保存发布后,会固定生成一个链接。而文章链接是会以固定的host地址mp.weixin.qq.com
进行发布,如下:
http://mp.weixin.qq.com/s?__biz=MzA5MTA2MzkyOQ==&mid=257050763&idx=1&sn=6984b946e5fd618a5f42e071d1729a7a&scene=0#rd
然后分析网页源码,在底部可以发现如下javascript代码:
<script type="text/javascript"> var not_in_mm_css = "http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/style/page/appmsg/not_in_mm2637ae.css"; var windowwx_css = "http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/style/page/appmsg/page_mp_article_improve_pc2637ae.css"; var tid = ""; var aid = ""; var appuin = "MzA5MTA2MzkyOQ=="; var source = "0"; var scene = 75; var itemidx = ""; var nickname = "CodeBoy助手"; var ct = "1438614177"; var user_name = "gh_7809f2e62230"; var user_name_new = ""; var fakeid = ""; var version = ""; var is_limit_user = "0"; var msg_title = "CodeBoy微信抢红包外挂"; var msg_desc = "Android微信抢红包外挂实现源码与详解"; var msg_cdn_url = "http://mmbiz.qpic.cn/mmbiz/mdBqiaB1jx3ATKrHYu0rg7tTIWEVLqz5nQuMNlvgianJDD7G33iao85IUVgQpjO11icJsmojlCY2XFAapyXiaMiafW5g/0?wx_fmt=jpeg"; var msg_link = "http://mp.weixin.qq.com/s?__biz=MzA5MTA2MzkyOQ==&mid=257050763&idx=1&sn=6984b946e5fd618a5f42e071d1729a7a#rd"; var user_uin = "0"*1; var msg_source_url = 'http://www.happycodeboy.com/index.php/archives/10/#rd'; var img_format = 'jpeg'; var networkType; var appmsgid = '' || '257050763'; var comment_id = "0" * 1; var svr_time = "1438966394" * 1; var comment_enabled = "" * 1; var is_need_reward = "0" * 1; var is_https_res = ("" * 1) && (location.protocol == "https:"); var devicetype = ""; var source_username = ""; var show_comment = ""; var __appmsgCgiData = { can_use_page : "0"*1, card_pos : "", copyright_stat : "0", hd_head_img : "http://wx.qlogo.cn/mmhead/Q3auHgzwzM54RqtxygzEE174cxI2BWaTDiaTtjWNaTObpib5bCnlGl4A/0"||(window.location.protocol+"//"+window.location.host + "http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/images/pic/appmsg/pic_rumor_link.2x264e76.jpg") }; var _empty_v = "http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/images/pic/pages/voice/empty26f1f1.mp3"; seajs.use("appmsg/index.js"); </script>
通过以上代码,我们就可以知道其中一些变量的对应关系
通过WebView读取javascript全局变量
通过上述分析,我们已经知道分享文章里的标题、描述、图片、链接是从哪里得到的,那接下来,我们就通过编码方式,去读取。
首先,我们要添加一个javascrtip访问到java层代码的入口,目的是为了回调javascript的全局变量到java层,webView.addJavascriptInterface(new CodeBoyJsInterface(), "codeboy");
而CodeBoyJsInterface
里有一个callme
方法。
接下来,在加载一个页面成功后,我们就要调用javascript的方法去读到全局变量。如:webview.loadUrl("javascript:window.codeboy.callme(msg_title)");
这样就在CodeBoyJsInterface.callme
的方法里回接收到msg_title
这个变量的值。就这样,可以实现一个获取javascript页面里变量,从而有更多进一步的操作。
以下是示例的完整代码:
package com.codeboy.android;import android.annotation.SuppressLint;import android.graphics.Bitmap;import android.os.Bundle;import android.os.Parcel;import android.os.Parcelable;import android.support.v7.app.AppCompatActivity;import android.text.Html;import android.text.TextUtils;import android.util.Log;import android.webkit.JavascriptInterface;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import org.json.JSONException;import org.json.JSONObject;public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; //缓存第一个加载的图片链接 private String cacheFirstLoadImageUrl = null; private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView) findViewById(R.id.webview); webView.setWebViewClient(new CBWebViewClient()); WebSettings settings = webView.getSettings(); //允许javascript的功能 settings.setJavaScriptEnabled(true); //自适应屏幕 settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); settings.setUseWideViewPort(true); settings.setLoadWithOverviewMode(true); //添加一个允许javascript访问方法,如 window.codeboy.callme("hello codeboy"); webView.addJavascriptInterface(new CodeBoyJsInterface(), "codeboy"); //加载测试的地址 webView.loadUrl("http://mp.weixin.qq.com/s?__biz=MzA5MTA2MzkyOQ==&mid=257050763&idx=1&sn=6984b946e5fd618a5f42e071d1729a7a&scene=0#rd"); } /* * tips * 实现Parcelable接口,主要是避免因为混淆而导致方法名变更 * */ @SuppressLint("JavascriptInterface") public class CodeBoyJsInterface implements Parcelable { public CodeBoyJsInterface() { } //解决throws Uncaught Error: Error calling method on NPObject on Android @JavascriptInterface public void callme(final String str) { //这里是javascript里回调的,注意回调是通过非UI线程 try { JSONObject json = new JSONObject(str); String msg_title = getJsonStr(json, "msg_title"); String msg_desc = getJsonStr(json, "msg_desc"); String msg_link = getJsonStr(json, "msg_link"); String msg_cdn_url = getJsonStr(json, "msg_cdn_url"); Log.d(TAG, "msg_title:" + msg_title + " msg_desc:" + msg_desc + " msg_link:" + msg_link + " msg_cdn_url:" + msg_cdn_url); } catch (JSONException e) { e.printStackTrace(); } } private String getJsonStr(JSONObject json, String key) { try { String value = json.getString(key); //对数据进行转义 return Html.fromHtml(value).toString(); } catch (JSONException e) { e.printStackTrace(); } return null; } @Override public int describeContents() { //ignore return 0; } @Override public void writeToParcel(Parcel dest, int flags) { //ignore } } class CBWebViewClient extends WebViewClient { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); Log.v(TAG, "onPageFinished 加载完成:" + url); //页面加载完毕后,判断是否为微信的公众平台文章 if (url.startsWith("http://mp.weixin.qq.com") || url.startsWith("https://mp.weixin.qq.com")) { //读取分享的信息,将数据以json的格式返回,方便日后扩展 view.loadUrl("javascript:window.codeboy.callme(JSON.stringify({" + "\"msg_title\":msg_title.toString()," + "\"msg_desc\":msg_desc.toString()," + "\"msg_link\":msg_link.toString()," + "\"msg_cdn_url\":msg_cdn_url.toString()" + "}))"); } } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); cacheFirstLoadImageUrl = null; } @Override public void onLoadResource(WebView view, String url) { super.onLoadResource(view, url); //读取加载中的资源里的图片 if (cacheFirstLoadImageUrl == null && !TextUtils.isEmpty(url)) { if (url.contains(".png") || url.contains(".jpg")) { cacheFirstLoadImageUrl = url; } } } }}
以下是运行的打印结果:
08-08 02:01:54.728 17198-17352/com.codeboy.android D/MainActivity﹕ msg_title:CodeBoy微信抢红包外挂 msg_desc:Android微信抢红包外挂实现源码与详解 msg_link:http://mp.weixin.qq.com/s?__biz=MzA5MTA2MzkyOQ==&mid=257050763&idx=1&sn=6984b946e5fd618a5f42e071d1729a7a#rd msg_cdn_url:http://mmbiz.qpic.cn/mmbiz/mdBqiaB1jx3ATKrHYu0rg7tTIWEVLqz5nQuMNlvgianJDD7G33iao85IUVgQpjO11icJsmojlCY2XFAapyXiaMiafW5g/0?wx_fmt=jpeg
版权声明:
文章为原创,CodeBoy版权所有,如需转载请注明出处。
本文来自:http://www.happycodeboy.com/index.php/archives/13/
关注微信订阅号:CodeBoy助手
- 了解Android微信里的WebView是如何实现分享的功能
- android分享功能的实现
- android分享功能的实现
- android分享功能的实现
- android 分享功能的实现
- Android 分享功能的实现
- Android 分享功能的实现
- Android分享功能的实现
- android: 如何开启webview的LBS功能
- android:如何开启webview的LBS功能
- Android webView是如何使用的
- Android如何实现分享功能
- 经验分享:thinkphp 5是如何实现验证码功能的
- Android中“分享”功能的实现
- Android中“分享”功能的实现
- Android中“分享”功能的实现
- Android中“分享”功能的实现
- Android中“分享”功能的实现
- GitHub for Windows的Git Shell 执行是颜色所代表的意义
- OC_NSUseDefault
- MySQL调优 ---- IN
- 黑马程序员_java_API总结
- 黑马程序员_java_IO流总结(上)
- 了解Android微信里的WebView是如何实现分享的功能
- 黑马程序员_java_IO流总结(中)
- 黑马程序员_java_IO流总结(下)
- 黑马程序员_java_多线程总结(上)
- 黑马程序员_java_多线程总结(下)
- 黑马程序员_java_反射总结
- 程序员该有的艺术气质—SOLID原则
- 犀牛——第7章 7.3稀疏数组
- 黑马程序员_java_集合总结(上)