Cordova(PhoneGap)通过plugins调用Android Native并回调

最近在学cordova,发现网上好多PhoneGap的plugins使用方法,一开始以为cordova也可以这样使用,但是实际是i think too much。现在cordova就相当于PhoneGap,所以使用plugins调用Android Java代码就使用现在cordova方法。


(1)配置cordova(phoneGap)参考下面两个链接:

http://www.zwlme.com/frontend/phonegap-getting-started-tutorial-1.html

http://blog.csdn.net/aaawqqq/article/details/19755179


注意:一定要配置好ANDROID_HOME及其他环境变量


如果用npm因为NetWork错误无法下载的话,请使用镜像

1.打开命令行输入 npm config set registry http://registry.cnpmjs.org

2.再输入 npm info underscore

3.编辑 ~/.npmrc  加入下面内容 registry = http://registry.cnpmjs.org


(2)导入项目结构如下



(3)实现html给android Activity传值

效果演示:


InputData.html显示三个输入框,并且输入数据



点击Enter按钮跳转到Activity——dataListActivity,显示了在html输入的内容,并且在EditText输出内容



点击sendback按钮,回调到html,并且用弹出框输出内容



实现步骤:


①在ivy.cordova.example包下有一个类MainActivity,其中的loadUrl方法就是加载了需要显示的html

  1. public class MainActivity extends CordovaActivity  
  2. {  
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState)  
  5.     {  
  6.         super.onCreate(savedInstanceState);  
  7.   
  8.         loadUrl("file:///android_asset/www/InputData.html");  
  9.     }  
  10. }  
public class MainActivity extends CordovaActivity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        loadUrl("file:///android_asset/www/InputData.html");
    }
}

②所以先写需要加载的html文件——InputData.html,请将该文件放在assets/www/该目录下


通过效果演示可以看到有三个输入框,那怎么获取输入框内容并且传给Activity呢?

  
  
  1. <script type="text/javascript" src="js/dataTransportJs.js"></script>  
  2.     <script type="text/javascript" charset="utf-8">  
  3.     document.addEventListener("deviceready", onDeviceReady, true);  
  4.   
  5.     function onDeviceReady(){  
  6.     //获取输入框和按钮对象  
  7.         var text1 = document.getElementById("name");  
  8.         var text2 = document.getElementById("Number");  
  9.         var text3 = document.getElementById("Age");  
  10.         var btn =document.getElementById("Enter");  
  11.   
  12.         //给对象加上监听  
  13.         btn.addEventListener('click', onClick);  
  14.   
  15.         function onClick(){  
  16.         //获取输入框值  
  17.             var Name =text1.value;  
  18.             var Number =text2.value;  
  19.             var Age =text3.value;  
  20.             var success = function(message) { alert("Success" + message); };  
  21.             var error = function(message) { alert("Oopsie! " + message); };  
  22.   
  23.             //用插件调用值  
  24.             dataTransportPlugins.createEvent(Name, Number, Age, success, error);  
  25.         }  
  26.     }  
  27.     </script>  
<script type="text/javascript" src="js/dataTransportJs.js"></script>
    <script type="text/javascript" charset="utf-8">
    document.addEventListener("deviceready", onDeviceReady, true);

    function onDeviceReady(){
    //获取输入框和按钮对象
        var text1 = document.getElementById("name");
        var text2 = document.getElementById("Number");
        var text3 = document.getElementById("Age");
        var btn =document.getElementById("Enter");

        //给对象加上监听
        btn.addEventListener('click', onClick);

        function onClick(){
        //获取输入框值
            var Name =text1.value;
            var Number =text2.value;
            var Age =text3.value;
            var success = function(message) { alert("Success" + message); };
            var error = function(message) { alert("Oopsie! " + message); };

            //用插件调用值
            dataTransportPlugins.createEvent(Name, Number, Age, success, error);
        }
    }
    </script>

以下代码就是调用了dataTransportPlugins这个插件里面的createEvent方法并且传递了五个参数:
  
  
  1. dataTransportPlugins.createEvent(Name, Number, Age, success, error);  
            dataTransportPlugins.createEvent(Name, Number, Age, success, error);

参数:1,2,3都是输入框的值,而success,error分别是调用成功和失败的回调方法,且message是通过插件plugin返回的Activity值

  
  
  1. var success = function(message) { alert("Success" + message); };  
  2. var error = function(message) { alert("Oopsie! " + message); };  
            var success = function(message) { alert("Success" + message); };
            var error = function(message) { alert("Oopsie! " + message); };

③但是要用这个插件的话,就需要定义它引入它,它不会无缘无故就可以使用的吧,所以用下面一句代码引入这个插件,那就是说插件其实是一个js文件

  
  
  1. <script type="text/javascript" src="js/dataTransportJs.js"></script>  
<script type="text/javascript" src="js/dataTransportJs.js"></script>

完整html代码:

  
  
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8" />  
  5.     <meta name="format-detection" content="telephone=no" />  
  6.     <meta name="msapplication-tap-highlight" content="no" />  
  7.     <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->  
  8.     <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />  
  9.     <link rel="stylesheet" type="text/css" href="css/index.css" />  
  10.     <title>InputData</title>  
  11.   
  12.     <script type="text/javascript" src="cordova.js"></script>  
  13.   
  14.     <script type="text/javascript" src="js/dataTransportJs.js"></script>  
  15.     <script type="text/javascript" charset="utf-8">  
  16.     document.addEventListener("deviceready", onDeviceReady, true);  
  17.   
  18.     function onDeviceReady(){  
  19.     //获取输入框和按钮对象  
  20.         var text1 = document.getElementById("name");  
  21.         var text2 = document.getElementById("Number");  
  22.         var text3 = document.getElementById("Age");  
  23.         var btn =document.getElementById("Enter");  
  24.   
  25.         //给对象加上监听  
  26.         btn.addEventListener('click', onClick);  
  27.   
  28.         function onClick(){  
  29.         //获取输入框值  
  30.             var Name =text1.value;  
  31.             var Number =text2.value;  
  32.             var Age =text3.value;  
  33.             var success = function(message) { alert("Success" + message); };  
  34.             var error = function(message) { alert("Oopsie! " + message); };  
  35.   
  36.             //用插件调用值  
  37.             dataTransportPlugins.createEvent(Name, Number, Age, success, error);  
  38.         }  
  39.     }  
  40.     </script>  
  41.   
  42. </head>  
  43.   
  44.   
  45. <body>  
  46.   
  47. <p>  
  48.     <label for="name"> Name: </label>  
  49.     <input type="text" name="input" id="name" value=""  />  
  50. </p>  
  51. <p>  
  52.     <label for="name"> Number: </label>  
  53.     <input type="text" name="input" id="Number" value="" />  
  54. </p>  
  55. <p>  
  56.     <label for="name"> Age: </label>  
  57.     <input type="text" name="input" id="Age" value="" />  
  58. </p>  
  59.   
  60. <button id="Enter">Enter</button>  
  61. </body>  
  62. </html>  
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="msapplication-tap-highlight" content="no" />
    <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
    <link rel="stylesheet" type="text/css" href="css/index.css" />
    <title>InputData</title>

    <script type="text/javascript" src="cordova.js"></script>

    <script type="text/javascript" src="js/dataTransportJs.js"></script>
    <script type="text/javascript" charset="utf-8">
    document.addEventListener("deviceready", onDeviceReady, true);

    function onDeviceReady(){
    //获取输入框和按钮对象
        var text1 = document.getElementById("name");
        var text2 = document.getElementById("Number");
        var text3 = document.getElementById("Age");
        var btn =document.getElementById("Enter");

        //给对象加上监听
        btn.addEventListener('click', onClick);

        function onClick(){
        //获取输入框值
            var Name =text1.value;
            var Number =text2.value;
            var Age =text3.value;
            var success = function(message) { alert("Success" + message); };
            var error = function(message) { alert("Oopsie! " + message); };

            //用插件调用值
            dataTransportPlugins.createEvent(Name, Number, Age, success, error);
        }
    }
    </script>

</head>


<body>

<p>
    <label for="name"> Name: </label>
    <input type="text" name="input" id="name" value=""  />
</p>
<p>
    <label for="name"> Number: </label>
    <input type="text" name="input" id="Number" value="" />
</p>
<p>
    <label for="name"> Age: </label>
    <input type="text" name="input" id="Age" value="" />
</p>

<button id="Enter">Enter</button>
</body>
</html>


④js文件相当于一个html和android交互的一个接口,js代码如下:

  
  
[javascript] view plain copy
print ?
  1. //在html被调用的插件  
  2. var dataTransportPlugins = {  
  3.   
  4.     //在html被调用的方法  
  5.     createEvent: function(Name, Number, Age, successCallback, errorCallback) {  
  6.       
  7.         cordova.exec(  
  8.           
  9.             //成功的回调  
  10.             successCallback,  
  11.               
  12.             //失败的回调  
  13.             errorCallback,  
  14.               
  15.             //java类插件名称  
  16.             'DataTransportPlugin',  
  17.               
  18.             //执行插件的动作  
  19.             'dataTransport',  
  20.               
  21.             //数据组这里以json形式  
  22.             [{  
  23.                 "Name": Name,  
  24.                 "Number": Number,  
  25.                 "Age": Age,  
  26.             }]  
  27.         );  
  28.     }  
  29. }  
//在html被调用的插件
var dataTransportPlugins = {

    //在html被调用的方法
    createEvent: function(Name, Number, Age, successCallback, errorCallback) {
    
        cordova.exec(
        
            //成功的回调
            successCallback,
            
            //失败的回调
            errorCallback,
            
            //java类插件名称
            'DataTransportPlugin',
            
            //执行插件的动作
            'dataTransport',
            
            //数据组这里以json形式
            [{
                "Name": Name,
                "Number": Number,
                "Age": Age,
            }]
        );
    }
}


参数1.2.略
参数3.js文件既然是一个接口,那就需要有一个实现接口的java类,这个参数就是实现类的名字
参数4.可以将java实现类想象成是一扇门,而这个参数就是一把钥匙,java实现类会通过对这个参数验证来判断有没有匹配的方法
参数5.html需要传给Activity的数据

数据组的写法是:
[参数1,参数2,……]

每个参数可以是以{}为一组的数据(代码例子),或者是单个值[name,number],他们获取的方法不同,但是都是以JSON的格式进行传递

⑤java实现类——DataTransportPlugin.java


  
  
  1. public class DataTransportPlugin extends CordovaPlugin {  
  2.   
  3.     //执行插件的动作,可以有多个动作  
  4.     public static final String ACTION_FLAG = "dataTransport";  
  5.   
  6.     CallbackContext callbackContext;  
  7.   
  8.     public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {  
  9.         try {  
  10.             //判断接口传来的动作是否跟定义的动作一致  
  11.             if (ACTION_FLAG.equals(action)) {  
  12.   
  13.                 this.callbackContext = callbackContext;  
  14.                 //获取json  
  15.                 JSONObject argJson = args.getJSONObject(0);  
  16.                 //解析json并且传递给Activity  
  17.                 Intent mIntent = new Intent();  
  18.                 mIntent.putExtra("Name",argJson.getString("Name"));  
  19.                 mIntent.putExtra("Number",argJson.getString("Number"));  
  20.                 mIntent.putExtra("Age",argJson.getString("Age"));  
  21.                 mIntent.setClass(cordova.getActivity(), dataListActivity.class);  
  22.                 this.cordova.startActivityForResult(this, mIntent, 1);  
  23.                 return true;  
  24.             }  
  25.             else{  
  26.                 callbackContext.error("Invalid action");  
  27.                 return false;  
  28.             }  
  29.   
  30.         } catch (Exception e) {  
  31.   
  32.             callbackContext.error(e.getMessage());  
  33.             return false;  
  34.         }  
  35.     }  
  36.   
  37.     /** 
  38.      * activity 的回调接收方法 
  39.      * @param requestCode   The request code originally supplied to startActivityForResult(), 
  40.      *                      allowing you to identify who this result came from. 
  41.      * @param resultCode    The integer result code returned by the child activity through its setResult(). 
  42.      * @param intent        An Intent, which can return result data to the caller (various data can be 
  43.      */  
  44.     public void onActivityResult(int requestCode, int resultCode, Intent intent) {  
  45.         switch (resultCode) {  
  46.             case Activity.RESULT_OK:  
  47.   
  48.                 //获得从Activity传来的值  
  49.                 Bundle b=intent.getExtras();  
  50.                 String str=b.getString("flags");  
  51.   
  52.                 //通过PluginResult和callbackContext返回给js接口  
  53.                 PluginResult pluginResults = new PluginResult(PluginResult.Status.OK, str);  
  54.                 callbackContext.sendPluginResult(pluginResults);  
  55.                 pluginResults.setKeepCallback(true);  
  56.                 callbackContext.success();  
  57.                 break;  
  58.             default:  
  59.                 break;  
  60.         }  
  61.     }  
  62. }  
public class DataTransportPlugin extends CordovaPlugin {

    //执行插件的动作,可以有多个动作
    public static final String ACTION_FLAG = "dataTransport";

    CallbackContext callbackContext;

    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        try {
            //判断接口传来的动作是否跟定义的动作一致
            if (ACTION_FLAG.equals(action)) {

                this.callbackContext = callbackContext;
                //获取json
                JSONObject argJson = args.getJSONObject(0);
                //解析json并且传递给Activity
                Intent mIntent = new Intent();
                mIntent.putExtra("Name",argJson.getString("Name"));
                mIntent.putExtra("Number",argJson.getString("Number"));
                mIntent.putExtra("Age",argJson.getString("Age"));
                mIntent.setClass(cordova.getActivity(), dataListActivity.class);
                this.cordova.startActivityForResult(this, mIntent, 1);
                return true;
            }
            else{
                callbackContext.error("Invalid action");
                return false;
            }

        } catch (Exception e) {

            callbackContext.error(e.getMessage());
            return false;
        }
    }

    /**
     * activity 的回调接收方法
     * @param requestCode   The request code originally supplied to startActivityForResult(),
     *                      allowing you to identify who this result came from.
     * @param resultCode    The integer result code returned by the child activity through its setResult().
     * @param intent        An Intent, which can return result data to the caller (various data can be
     */
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        switch (resultCode) {
            case Activity.RESULT_OK:

                //获得从Activity传来的值
                Bundle b=intent.getExtras();
                String str=b.getString("flags");

                //通过PluginResult和callbackContext返回给js接口
                PluginResult pluginResults = new PluginResult(PluginResult.Status.OK, str);
                callbackContext.sendPluginResult(pluginResults);
                pluginResults.setKeepCallback(true);
                callbackContext.success();
                break;
            default:
                break;
        }
    }
}

通过下面的代码可以获取html传递过来的数据,例子中只有一个以{}包括的参数
  1. //获取json  
  2. JSONObject argJson = args.getJSONObject(0);  
                //获取json
                JSONObject argJson = args.getJSONObject(0);

通过以下代码解析了json并且跳转到Activity——dataListActivity(跳转方法用startActivityForResult,则说明需要有OnActivityResult方法来接收dataListActivity回传的数据

  
  
  1. //解析json并且传递给Activity  
  2.                Intent mIntent = new Intent();  
  3.                mIntent.putExtra("Name",argJson.getString("Name"));  
  4.                mIntent.putExtra("Number",argJson.getString("Number"));  
  5.                mIntent.putExtra("Age",argJson.getString("Age"));  
  6.                mIntent.setClass(cordova.getActivity(), dataListActivity.class);  
  7.                this.cordova.startActivityForResult(this, mIntent, 1);  
 //解析json并且传递给Activity
                Intent mIntent = new Intent();
                mIntent.putExtra("Name",argJson.getString("Name"));
                mIntent.putExtra("Number",argJson.getString("Number"));
                mIntent.putExtra("Age",argJson.getString("Age"));
                mIntent.setClass(cordova.getActivity(), dataListActivity.class);
                this.cordova.startActivityForResult(this, mIntent, 1);

通过以下代码,将从dataListActivity回传的数据和一个成功的标识PluginResult.Status.OK包装成一个PluginResult对象,通过CallbackContext对象发送PluginResult

  
  
  1. //通过PluginResult和callbackContext返回给js接口  
  2.                PluginResult pluginResults = new PluginResult(PluginResult.Status.OK, str);  
  3.                callbackContext.sendPluginResult(pluginResults);  
  4.                pluginResults.setKeepCallback(true);  
  5.                callbackContext.success();  
 //通过PluginResult和callbackContext返回给js接口
                PluginResult pluginResults = new PluginResult(PluginResult.Status.OK, str);
                callbackContext.sendPluginResult(pluginResults);
                pluginResults.setKeepCallback(true);
                callbackContext.success();

 
 
⑥dataListActivity.java
   
   
  1. public class dataListActivity extends Activity {  
  2.         private Button bt;  
  3.         private EditText et;  
  4.         private TextView tv1,tv2,tv3;  
  5.         private Intent mIntent;  
  6.         public void onCreate(Bundle savedInstanceState) {  
  7.             super.onCreate(savedInstanceState);  
  8.             setContentView(R.layout.main);  
  9.   
  10.             bt =(Button)findViewById(R.id.bt);  
  11.             et =(EditText)findViewById(R.id.et);  
  12.             tv1 =(TextView)findViewById(R.id.tv1);  
  13.             tv2 =(TextView)findViewById(R.id.tv2);  
  14.             tv3 =(TextView)findViewById(R.id.tv3);  
  15.   
  16.             //获取Intent的值  
  17.             mIntent = this.getIntent();  
  18.             tv1.setText("Name: "+ mIntent.getStringExtra("Name"));  
  19.             tv2.setText("Number: "+ mIntent.getStringExtra("Number"));  
  20.             tv3.setText("Age: "+ mIntent.getStringExtra("Age"));  
  21.   
  22.             bt.setOnClickListener(new View.OnClickListener() {  
  23.   
  24.                 public void onClick(View v) {  
  25.   
  26.                     //回调值  
  27.                     String msg = et.getText().toString();  
  28.                     mIntent.putExtra("flags""msg from Activity: " + msg);  
  29.                     setResult(RESULT_OK, mIntent);  
  30.                     finish();  
  31.                 }  
  32.             });  
  33.         }  
  34.     }  
public class dataListActivity extends Activity {
        private Button bt;
        private EditText et;
        private TextView tv1,tv2,tv3;
        private Intent mIntent;
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            bt =(Button)findViewById(R.id.bt);
            et =(EditText)findViewById(R.id.et);
            tv1 =(TextView)findViewById(R.id.tv1);
            tv2 =(TextView)findViewById(R.id.tv2);
            tv3 =(TextView)findViewById(R.id.tv3);

            //获取Intent的值
            mIntent = this.getIntent();
            tv1.setText("Name: "+ mIntent.getStringExtra("Name"));
            tv2.setText("Number: "+ mIntent.getStringExtra("Number"));
            tv3.setText("Age: "+ mIntent.getStringExtra("Age"));

            bt.setOnClickListener(new View.OnClickListener() {

                public void onClick(View v) {

                    //回调值
                    String msg = et.getText().toString();
                    mIntent.putExtra("flags", "msg from Activity: " + msg);
                    setResult(RESULT_OK, mIntent);
                    finish();
                }
            });
        }
    }

⑦还需要在res/xml/config.xml文件中的widget标签下注册插件
   
   
  1. <feature name="DataTransportPlugin">  
  2.         <param name="android-package" value="ivy.cordova.example.plugins.DataTransportPlugin" />  
  3.     </feature>  
<feature name="DataTransportPlugin">
        <param name="android-package" value="ivy.cordova.example.plugins.DataTransportPlugin" />
    </feature>


⑧在AndroidManifest.xml中注册dataListActivity页面
    
    
  1. <activity android:name=".dataListActivity" android:theme="@style/AppTheme"/>  
<activity android:name=".dataListActivity" android:theme="@style/AppTheme"/>

目录结构:


系列文章:XX程序媛学习笔记--Cordova(PhoneGap)通过plugins调用Android Native并回调


参考博客:

http://www.cnblogs.com/lee0oo0/archive/2012/06/07/2540059.html

http://www.tuicool.com/articles/6N3yie

http://blog.csdn.net/knxw0001/article/details/11219811

http://rensanning.iteye.com/blog/2163892

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值