Javascript | 安卓实现微信jssdk扫一扫带参数的回

2017-01-09  本文已影响449人  卖小女孩的小火柴

前言,最近有个项目要做一个安卓和iOS的App,实质上是通过调用webview来加载网页,但是需要实现微信扫一扫类似的功能,那就只能通过js来调用安卓/iOS中暴露出来调用扫一扫的接口,不过通过搜网上的一些关于安卓和js互调的文章,都只是介绍了一些关于安卓系统和js互调的基本原理和实现,并没有类似于实现像微信扫一扫一样的通过回调函数来处理微信扫一扫的结果的相关教程。那么咱们就得自力更生,来研究下怎样才能实现微信扫一扫类似的功能。

我们就拿安卓的来说。
第一步:
mainfest.xml中加入网络权限

<uses-permission android:name="android.permission.INTERNET" />  

第二步:
加载本地写好的html文件(定义好js中提供给android调用的方法 funFromjs(),和android提供给js调用的对象接口fun1FromAndroid(String name)),放在 assets目录下。

<body>  
    <a>js中调用本地方法</a>  
    <script>  
      
    function funFromjs(){  
        document.getElementById("helloweb").innerHTML="HelloWebView,i'm from js";  
    }  
    var aTag = document.getElementsByTagName('a')[0];  
    aTag.addEventListener('click', function(){  
        //调用android本地方法  
        myObj.fun1FromAndroid("调用android本地方法fun1FromAndroid(String name)!!");  
        return false;  
    }, false);  
    </script>  
    <p></p>  
    <div id="helloweb">   
  
    </div>  
</body>  

第三步:
实现android工程与js交互的相关代码,其中loadUrl()是实现安卓将js代码注入到webview里的关键
android代码:

@SuppressLint({ "JavascriptInterface", "SetJavaScriptEnabled" })  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
       super.onCreate(savedInstanceState);  
       setContentView(R.layout.activity_main);  
       //初始化  
       initViews();  
  
       //设置编码  
       mWebView.getSettings().setDefaultTextEncodingName("utf-8");  
       //支持js  
       mWebView.getSettings().setJavaScriptEnabled(true);  
       //设置背景颜色 透明  
       mWebView.setBackgroundColor(Color.argb(0, 0, 0, 0));  
       //设置本地调用对象及其接口  
       mWebView.addJavascriptInterface(new JavaScriptObject(mContext), "myObj");  
       //载入js  
       mWebView.loadUrl("file:///android_asset/test.html");  
         
       //点击调用js中方法  
       mBtn1.setOnClickListener(new View.OnClickListener() {  
  
           @Override  
           public void onClick(View v) {  
               mWebView.loadUrl("javascript:funFromjs()");  
               Toast.makeText(mContext, "调用javascript:funFromjs()", Toast.LENGTH_LONG).show();  
           }  
       });  
   }  

js调用的android对象方法定义

public class JavaScriptObject {  
    Context mContxt;  
    @JavascriptInterface //sdk17版本以上加上注解  
    public JavaScriptObject(Context mContxt) {  
        this.mContxt = mContxt;  
    }  
  
    public void fun1FromAndroid(String name) {  
        Toast.makeText(mContxt, name, Toast.LENGTH_LONG).show();  
    }  
  
    public void fun2(String name) {  
        Toast.makeText(mContxt, "调用fun2:" + name, Toast.LENGTH_SHORT).show();  
    }  
}  

以上代码借鉴了网友们一些代码_~
下面开始本文的核心代码,我们将html的代码改造下

<body>  
    <a>js中调用本地方法</a>  
    <script>  
      
    function funFromjs(){  
        document.getElementById("helloweb").innerHTML="HelloWebView,i'm from js";  
    }  
    //先定义一个scan函数,参数cb
    function scan(cb){
        if(typeof cb == "function"){
            //将cb强制类型转化成字符串类型,cb就是回调函数
            cb = String(cb);
        }else{
            cb = String(cb);
        }
        myObj.fun1FromAndroid(cb);
    }
    var aTag = document.getElementsByTagName('a')[0];  
    aTag.addEventListener('click', function(){  
        //调用android本地方法  
        //下面我们来调用这个scan函数并传入回调函数
        scan(function(str){
             alert(str); 
        });
        return false;  
    }, false);  
    </script>  
    <p></p>  
    <div id="helloweb">   
  
    </div>  
</body>  

//然后再改造安卓的java代码:

public class JavaScriptObject {  
    Context mContxt;  
    @JavascriptInterface //sdk17版本以上加上注解  
    public JavaScriptObject(Context mContxt) {  
        this.mContxt = mContxt;  
    }  
  
    public void fun1FromAndroid(String name) {  
        //这里将name的数据暂存起来,方便loadUrl注入js的时候调用,具体的代码就不展示了
        Toast.makeText(mContxt, name, Toast.LENGTH_LONG).show();  
    }  
  
    public void fun2(String name) {  
        Toast.makeText(mContxt, "调用fun2:" + name, Toast.LENGTH_SHORT).show();  
    }  
}  

然后是安卓activity里的代码改造:

@SuppressLint({ "JavascriptInterface", "SetJavaScriptEnabled" })  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
       super.onCreate(savedInstanceState);  
       setContentView(R.layout.activity_main);  
       //初始化  
       initViews();  
  
       //设置编码  
       mWebView.getSettings().setDefaultTextEncodingName("utf-8");  
       //支持js  
       mWebView.getSettings().setJavaScriptEnabled(true);  
       //设置背景颜色 透明  
       mWebView.setBackgroundColor(Color.argb(0, 0, 0, 0));  
       //设置本地调用对象及其接口  
       mWebView.addJavascriptInterface(new JavaScriptObject(mContext), "myObj");  
       //载入js  
       mWebView.loadUrl("file:///android_asset/test.html");  
         
       //点击调用js中方法  
       mBtn1.setOnClickListener(new View.OnClickListener() {  
  
           @Override  
           public void onClick(View v) {  
               mWebView.loadUrl("javascript:funFromjs()");  
               Toast.makeText(mContext, "调用javascript:funFromjs()", Toast.LENGTH_LONG).show();  
           }  
       });  
   }  
//我们现在考虑的是扫一扫的功能,需要在另一个页面实现调用摄像头,并读取到二维码的信息,并存储下来,在摄像头页面销毁后,回到上个页面
@Override
protected void onResume(Bundle savedInstanceState) {  
      //具体的数据代码就不写了
      String jsCode;//假设这个是webview里传进来回调函数的字符串
      String scanResualt;//假设这个是扫码之后的结果
      mWebView.loadUrl("javascript:var app = "+jsCode+";app(' "+scanResualt+" ');");//解释:这里将前台传递回调函数字符串赋值给一个变量app,接着再调用这个刚定义的app函数,并将扫码结果以参数形式传递给app这个函数;这样我们能实现类似微信扫一扫这样从html端的js传递匿名函数(带参数),并以js传递不同的回调函数来处理安卓系统返回的字符串
}

结语:上面的代码可能不够严谨,只是提供了这样的一个思路,可能还有其他更好的实现方法,iOS中webview的实现方式跟安卓的差不多,如果有什么疑问可以留言或者私信。

上一篇 下一篇

猜你喜欢

热点阅读